Skip to content

[mypyc] Faster len(bytes) #10936

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 3 commits into from
Aug 5, 2021
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
6 changes: 4 additions & 2 deletions mypyc/irbuild/ll_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
is_list_rprimitive, is_tuple_rprimitive, is_dict_rprimitive, is_set_rprimitive, PySetObject,
none_rprimitive, RTuple, is_bool_rprimitive, is_str_rprimitive, c_int_rprimitive,
pointer_rprimitive, PyObject, PyListObject, bit_rprimitive, is_bit_rprimitive,
object_pointer_rprimitive, c_size_t_rprimitive, dict_rprimitive, bytes_rprimitive
object_pointer_rprimitive, c_size_t_rprimitive, dict_rprimitive, bytes_rprimitive,
is_bytes_rprimitive
)
from mypyc.ir.func_ir import FuncDecl, FuncSignature
from mypyc.ir.class_ir import ClassIR, all_concrete_classes
Expand Down Expand Up @@ -1348,7 +1349,8 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val
"""
typ = val.type
size_value = None
if is_list_rprimitive(typ) or is_tuple_rprimitive(typ):
if (is_list_rprimitive(typ) or is_tuple_rprimitive(typ)
or is_bytes_rprimitive(typ)):
elem_address = self.add(GetElementPtr(val, PyVarObject, 'ob_size'))
size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address))
self.add(KeepAlive([val]))
Expand Down
19 changes: 17 additions & 2 deletions mypyc/test-data/irbuild-bytes.test
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,8 @@ L0:
c = r6
return 1


[case testBytesJoin]
from typing import List

def f(b: List[bytes]) -> bytes:
return b" ".join(b)
[out]
Expand All @@ -76,3 +74,20 @@ L0:
r0 = b' '
r1 = CPyBytes_Join(r0, b)
return r1

[case testBytesLen]
def f(b: bytes) -> int:
return len(b)
[out]
def f(b):
b :: bytes
r0 :: ptr
r1 :: native_int
r2 :: short_int
L0:
r0 = get_element_ptr b ob_size :: PyVarObject
r1 = load_mem r0 :: native_int*
keep_alive b
r2 = r1 << 1
return r2

4 changes: 3 additions & 1 deletion mypyc/test-data/run-bytes.test
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def test_len() -> None:
[case testBytearrayBasics]
from typing import Any

def test_init() -> None:
def test_basics() -> None:
brr1: bytes = bytearray(3)
assert brr1 == bytearray(b'\x00\x00\x00')
assert brr1 == b'\x00\x00\x00'
Expand All @@ -89,6 +89,8 @@ def test_init() -> None:
brr4: bytes = bytearray('string', 'utf-8')
assert brr4 == bytearray(b'string')
assert brr4 == b'string'
assert len(brr1) == 3
assert len(brr2) == 4

def f(b: bytes) -> bool:
return True
Expand Down