8000 Preallocate strings in a smarter way + add str.rmul by Jongy · Pull Request #913 · RustPython/RustPython · GitHub
[go: up one dir, main page]

Skip to content

Preallocate strings in a smarter way + add str.rmul #913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions tests/snippets/membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
assert "whatever" not in "foobar"

# test bytes
# TODO: uncomment this when bytes are implemented
# assert b"foo" in b"foobar"
# assert b"whatever" not in b"foobar"
assert b"foo" in b"foobar"
assert b"whatever" not in b"foobar"
assert b"1" < b"2"
assert b"1" <= b"2"
assert b"5" <= b"5"
Expand All @@ -32,18 +31,20 @@
assert 3 not in set([1, 2])

# test dicts
# TODO: test dicts when keys other than strings will be allowed
assert "a" in {"a": 0, "b": 0}
assert "c" not in {"a": 0, "b": 0}
assert 1 in {1: 5, 7: 12}
assert 5 not in {9: 10, 50: 100}
assert True in {True: 5}
assert False not in {True: 5}

# test iter
assert 3 in iter([1, 2, 3])
assert 3 not in iter([1, 2])

# test sequence
# TODO: uncomment this when ranges are usable
# assert 1 in range(0, 2)
# assert 3 not in range(0, 2)
assert 1 in range(0, 2)
assert 3 not in range(0, 2)

# test __contains__ in user objects
class MyNotContainingClass():
Expand Down
9 changes: 9 additions & 0 deletions tests/snippets/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@

assert str(["a", "b", "can't"]) == "['a', 'b', \"can't\"]"

assert "xy" * 3 == "xyxyxy"
assert "x" * 0 == ""
assert "x" * -1 == ""

assert 3 * "xy" == "xyxyxy"
assert 0 * "x" == ""
assert -1 * "x" == ""

a = 'Hallo'
assert a.lower() == 'hallo'
assert a.upper() == 'HALLO'
Expand Down Expand Up @@ -94,6 +102,7 @@
]


# requires CPython 3.7, and the CI currently runs with 3.6
# assert c.isascii()
assert c.index('a') == 1
assert c.rindex('l') == 3
Expand Down
16 changes: 13 additions & 3 deletions vm/src/obj/objstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ impl PyString {
if objtype::isinstance(&val, &vm.ctx.int_type()) {
let value = &self.value;
let multiplier = objint::get_value(&val).to_i32().unwrap();
let mut result = String::new();
let capacity = if multiplier > 0 {
multiplier.to_usize().unwrap() * value.len()
} else {
0
};
let mut result = String::with_capacity(capacity);
for _x in 0..multiplier {
result.push_str(value.as_str());
}
Expand All @@ -193,6 +198,11 @@ impl PyString {
}
}

#[pymethod(name = "__rmul__")]
fn rmul(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
self.mul(val, vm)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downside with this simple impl is that the raised TypeError shows the values swapped (As per the order of __mul__, not __rmul__).

On the other hand, the shown message (still?) doesn't match the one given by CPython, so we can be less pedantic about it.

}

#[pymethod(name = "__str__")]
fn str(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyStringRef {
zelf
Expand All @@ -206,7 +216,7 @@ impl PyString {
} else {
'\''
};
let mut formatted = String::new();
let mut formatted = String::with_capacity(value.len());
formatted.push(quote_char);
for c in value.chars() {
if c == quote_char || c == '\\' {
Expand Down Expand Up @@ -799,7 +809,7 @@ impl PyString {
#[pymethod]
fn expandtabs(&self, tab_stop: OptionalArg<usize>, _vm: &VirtualMachine) -> String {
let tab_stop = tab_stop.into_option().unwrap_or(8 as usize);
let mut expanded_str = String::new();
let mut expanded_str = String::with_capacity(self.value.len());
let mut tab_size = tab_stop;
let mut col_count = 0 as usize;
for ch in self.value.chars() {
Expand Down
0