mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #1696 from alvinlindstam/string-performance
String performance
This commit is contained in:
4
benchmarks/benchmarks/strings.py
Normal file
4
benchmarks/benchmarks/strings.py
Normal file
@@ -0,0 +1,4 @@
|
||||
long_string = "a" * 50000
|
||||
|
||||
for char in long_string:
|
||||
pass
|
||||
@@ -18,6 +18,7 @@ pythons = [
|
||||
benchmarks = [
|
||||
['benchmarks/nbody.py'],
|
||||
['benchmarks/mandelbrot.py'],
|
||||
['benchmarks/strings.py'],
|
||||
]
|
||||
|
||||
exe_ids = ['cpython', 'rustpython']
|
||||
|
||||
@@ -277,7 +277,7 @@ assert "\u9487" == "钇"
|
||||
assert "\U0001F609" == "😉"
|
||||
|
||||
# test str iter
|
||||
iterable_str = "123456789"
|
||||
iterable_str = "12345678😉"
|
||||
str_iter = iter(iterable_str)
|
||||
|
||||
assert next(str_iter) == "1"
|
||||
@@ -288,13 +288,13 @@ assert next(str_iter) == "5"
|
||||
assert next(str_iter) == "6"
|
||||
assert next(str_iter) == "7"
|
||||
assert next(str_iter) == "8"
|
||||
assert next(str_iter) == "9"
|
||||
assert next(str_iter) == "😉"
|
||||
assert next(str_iter, None) == None
|
||||
assert_raises(StopIteration, next, str_iter)
|
||||
|
||||
str_iter_reversed = reversed(iterable_str)
|
||||
|
||||
assert next(str_iter_reversed) == "9"
|
||||
assert next(str_iter_reversed) == "😉"
|
||||
assert next(str_iter_reversed) == "8"
|
||||
assert next(str_iter_reversed) == "7"
|
||||
assert next(str_iter_reversed) == "6"
|
||||
|
||||
@@ -98,7 +98,7 @@ impl TryIntoRef<PyString> for &str {
|
||||
#[derive(Debug)]
|
||||
pub struct PyStringIterator {
|
||||
pub string: PyStringRef,
|
||||
position: Cell<usize>,
|
||||
byte_position: Cell<usize>,
|
||||
}
|
||||
|
||||
impl PyValue for PyStringIterator {
|
||||
@@ -111,15 +111,16 @@ impl PyValue for PyStringIterator {
|
||||
impl PyStringIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
let pos = self.position.get();
|
||||
let pos = self.byte_position.get();
|
||||
|
||||
if pos < self.string.value.chars().count() {
|
||||
self.position.set(self.position.get() + 1);
|
||||
if pos < self.string.value.len() {
|
||||
// We can be sure that chars() has a value, because of the pos check above.
|
||||
let char_ = self.string.value[pos..].chars().next().unwrap();
|
||||
|
||||
#[allow(clippy::range_plus_one)]
|
||||
let value = self.string.value.do_slice(pos..pos + 1);
|
||||
self.byte_position
|
||||
.set(self.byte_position.get() + char_.len_utf8());
|
||||
|
||||
value.into_pyobject(vm)
|
||||
char_.to_string().into_pyobject(vm)
|
||||
} else {
|
||||
Err(objiter::new_stop_iteration(vm))
|
||||
}
|
||||
@@ -1198,7 +1199,7 @@ impl PyString {
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyStringIterator {
|
||||
PyStringIterator {
|
||||
position: Cell::new(0),
|
||||
byte_position: Cell::new(0),
|
||||
string: zelf,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user