Skip to content

Commit a0c34da

Browse files
authored
Optimize bytes-like (l|r)strip (#4500)
1 parent 1d81546 commit a0c34da

File tree

3 files changed

+62
-24
lines changed

3 files changed

+62
-24
lines changed

vm/src/builtins/bytearray.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,37 @@ impl PyByteArray {
507507
}
508508

509509
#[pymethod]
510-
fn lstrip(&self, chars: OptionalOption<PyBytesInner>) -> Self {
511-
self.inner().lstrip(chars).into()
510+
fn lstrip(
511+
zelf: PyRef<Self>,
512+
chars: OptionalOption<PyBytesInner>,
513+
vm: &VirtualMachine,
514+
) -> PyRef<Self> {
515+
let inner = zelf.inner();
516+
let stripped = inner.lstrip(chars);
517+
let elements = &inner.elements;
518+
if stripped == elements {
519+
drop(inner);
520+
zelf
521+
} else {
522+
vm.new_pyref(PyByteArray::from(stripped.to_vec()))
523+
}
512524
}
513525

514526
#[pymethod]
515-
fn rstrip(&self, chars: OptionalOption<PyBytesInner>) -> Self {
516-
self.inner().rstrip(chars).into()
527+
fn rstrip(
528+
zelf: PyRef<Self>,
529+
chars: OptionalOption<PyBytesInner>,
530+
vm: &VirtualMachine,
531+
) -> PyRef<Self> {
532+
let inner = zelf.inner();
533+
let stripped = inner.rstrip(chars);
534+
let elements = &inner.elements;
535+
if stripped == elements {
536+
drop(inner);
537+
zelf
538+
} else {
539+
vm.new_pyref(PyByteArray::from(stripped.to_vec()))
540+
}
517541
}
518542

519543
/// removeprefix($self, prefix, /)

vm/src/builtins/bytes.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,31 @@ impl PyBytes {
366366
}
367367

368368
#[pymethod]
369-
fn lstrip(&self, chars: OptionalOption<PyBytesInner>) -> Self {
370-
self.inner.lstrip(chars).into()
369+
fn lstrip(
370+
zelf: PyRef<Self>,
371+
chars: OptionalOption<PyBytesInner>,
372+
vm: &VirtualMachine,
373+
) -> PyRef<Self> {
374+
let stripped = zelf.inner.lstrip(chars);
375+
if stripped == zelf.as_bytes() {
376+
zelf
377+
} else {
378+
vm.ctx.new_bytes(stripped.to_vec())
379+
}
371380
}
372381

373382
#[pymethod]
374-
fn rstrip(&self, chars: OptionalOption<PyBytesInner>) -> Self {
375-
self.inner.rstrip(chars).into()
383+
fn rstrip(
384+
zelf: PyRef<Self>,
385+
chars: OptionalOption<PyBytesInner>,
386+
vm: &VirtualMachine,
387+
) -> PyRef<Self> {
388+
let stripped = zelf.inner.rstrip(chars);
389+
if stripped == zelf.as_bytes().to_vec() {
390+
zelf
391+
} else {
392+
vm.ctx.new_bytes(stripped.to_vec())
393+
}
376394
}
377395

378396
/// removeprefix($self, prefix, /)

vm/src/bytesinner.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -576,24 +576,20 @@ impl PyBytesInner {
576576
.to_vec()
577577
}
578578

579-
pub fn lstrip(&self, chars: OptionalOption<PyBytesInner>) -> Vec<u8> {
580-
self.elements
581-
.py_strip(
582-
chars,
583-
|s, chars| s.trim_start_with(|c| chars.contains(&(c as u8))),
584-
|s| s.trim_start(),
585-
)
586-
.to_vec()
579+
pub fn lstrip(&self, chars: OptionalOption<PyBytesInner>) -> &[u8] {
580+
self.elements.py_strip(
581+
chars,
582+
|s, chars| s.trim_start_with(|c| chars.contains(&(c as u8))),
583+
|s| s.trim_start(),
584+
)
587585
}
588586

589-
pub fn rstrip(&self, chars: OptionalOption<PyBytesInner>) -> Vec<u8> {
590-
self.elements
591-
.py_strip(
592-
chars,
593-
|s, chars| s.trim_end_with(|c| chars.contains(&(c as u8))),
594-
|s| s.trim_end(),
595-
)
596-
.to_vec()
587+
pub fn rstrip(&self, chars: OptionalOption<PyBytesInner>) -> &[u8] {
588+
self.elements.py_strip(
589+
chars,
590+
|s, chars| s.trim_end_with(|c| chars.contains(&(c as u8))),
591+
|s| s.trim_end(),
592+
)
597593
}
598594

599595
// new in Python 3.9

0 commit comments

Comments
 (0)