Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[mypyc] Precompute set literals for "in" ops against / iteration over set literals#14409

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
JukkaL merged 17 commits intopython:masterfromichard26:faster-in-for-set-literals
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
17 commits
Select commitHold shift + click to select a range
b0f57ab
mypyc: cherry picked wip from a year ago
ichard26Aug 12, 2021
c8d2dda
[wip] [mypyc] Precompute set literals for in ops
ichard26Aug 24, 2022
779a598
Stablize pprint of frozenset literals
ichard26Jan 6, 2023
7fabcfe
Fix byte literals & clean up precompute_set_literal()
ichard26Jan 6, 2023
97faab5
[wip] more tests
ichard26Jan 6, 2023
3ccf951
Update irbuild and add run tests
ichard26Jan 6, 2023
de47fef
Merge branch 'master' into faster-in-for-set-literals
ichard26Jan 6, 2023
0036e20
Clean up patch & add boolean to tests
ichard26Jan 6, 2023
e1527e2
Optimize for ... in <set-literal>
ichard26Jan 7, 2023
e3d3045
Oh look, I found constant_fold_expr()
ichard26Jan 7, 2023
8d68a7b
Run flake8/isort
ichard26Jan 7, 2023
1b75b7d
I forgot Final is a 3.8+ feature >.<
ichard26Jan 7, 2023
1a55fa4
Work around mypyc bug ...
ichard26Jan 7, 2023
3d44293
Work around mypyc bug ... attempt 2
ichard26Jan 7, 2023
fefac47
Work around mypyc bug ... attempt 3
ichard26Jan 7, 2023
9cdfc98
Add error handling + use test_* syntax instead
ichard26Jan 9, 2023
2f18f30
Improve precompute_set_literal() docstring
ichard26Jan 9, 2023
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
PrevPrevious commit
NextNext commit
Clean up patch & add boolean to tests
  • Loading branch information
@ichard26
ichard26 committedJan 7, 2023
commit0036e204b6558eff964bc3177cdf4c3e4378a85e
12 changes: 6 additions & 6 deletionsmypyc/analysis/ircheck.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -252,14 +252,14 @@ def check_tuple_items_valid_literals(self, op: LoadLiteral, t: tuple[object, ...
if isinstance(x, tuple):
self.check_tuple_items_valid_literals(op, x)

def check_frozenset_items_valid_literals(
self, op: LoadLiteral, s: frozenset[object, ...]
) -> None:
def check_frozenset_items_valid_literals(self, op: LoadLiteral, s: frozenset[object]) -> None:
for x in s:
if x isnotNoneand notisinstance(x, (str, bytes, bool, int, float, complex, tuple)):
self.fail(op, f"Invalid type for item of frozenset literal: {type(x)})")
if isinstance(x, tuple):
if x is Noneorisinstance(x, (str, bytes, bool, int, float, complex)):
pass
elif isinstance(x, tuple):
self.check_tuple_items_valid_literals(op, x)
else:
self.fail(op, f"Invalid type for item of frozenset literal: {type(x)})")

def visit_load_literal(self, op: LoadLiteral) -> None:
expected_type = None
Expand Down
15 changes: 2 additions & 13 deletionsmypyc/ir/ops.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@
)

if TYPE_CHECKING:
from mypyc.codegen.literals import LiteralValue
from mypyc.ir.class_ir import ClassIR
from mypyc.ir.func_ir import FuncDecl, FuncIR

Expand DownExpand Up@@ -603,19 +604,7 @@ class LoadLiteral(RegisterOp):
error_kind = ERR_NEVER
is_borrowed = True

def __init__(
self,
value: None
| str
| bytes
| bool
| int
| float
| complex
| tuple[object, ...]
| frozenset[object],
rtype: RType,
) -> None:
def __init__(self, value: LiteralValue, rtype: RType) -> None:
self.value = value
self.type = rtype

Expand Down
11 changes: 8 additions & 3 deletionsmypyc/ir/pprint.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,9 +109,14 @@ def visit_load_literal(self, op: LoadLiteral) -> str:

rvalue = repr(op.value)
if isinstance(op.value, frozenset):
# Pretty print frozensets in a hacky but stable way.
sorted_items = sorted(op.value, key=str)
rvalue = "frozenset({" + repr(sorted_items)[1:-1] + "})"
# We need to generate a string representation that won't vary
# run-to-run because sets are unordered, otherwise we may get
# spurious irbuild test failures.
#
# Sorting by the item's string representation is a bit of a
# hack, but it's stable and won't cause TypeErrors.
formatted_items = [repr(i) for i in sorted(op.value, key=str)]
rvalue = "frozenset({" + ", ".join(formatted_items) + "})"
return self.format("%r = %s%s", op, prefix, rvalue)

def visit_get_attr(self, op: GetAttr) -> str:
Expand Down
12 changes: 6 additions & 6 deletionsmypyc/irbuild/expression.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -718,15 +718,15 @@ def transform_comparison_expr(builder: IRBuilder, e: ComparisonExpr) -> Value:
and len(e.operators) == 1
and isinstance(e.operands[1], SetExpr)
):
literal = precompute_set_literal(builder, e.operands[1])
ifliteral is not None:
set_literal = precompute_set_literal(builder, e.operands[1])
ifset_literal is not None:
lhs = e.operands[0]
v = builder.builder.call_c(
set_in_op, [builder.accept(lhs),literal], e.line, bool_rprimitive
result = builder.builder.call_c(
set_in_op, [builder.accept(lhs),set_literal], e.line, bool_rprimitive
)
if first_op == "not in":
return builder.unary_op(v, "not", e.line)
returnv
return builder.unary_op(result, "not", e.line)
returnresult

if len(e.operators) == 1:
# Special some common simple cases
Expand Down
50 changes: 26 additions & 24 deletionsmypyc/test-data/irbuild-set.test
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -663,11 +663,11 @@ CONST: Final = "daylily"
non_const = 10

def precomputed(i: object) -> bool:
return i in {1, 2.7, 1j, "foo", b"bar", CONST, (None, (27,))}
return i in {1, 2.7, 1j, "foo", b"bar", CONST, (None, (27,)), (), False}
def not_precomputed_non_final_name(i: int) -> bool:
return i in {non_const}
def not_precomputed_nested_set(i: int) -> bool:
return i in {{1}, 2}
return i in {frozenset({1}), 2}
def not_precomputed_add_operation(i: int) -> bool:
# TODO: support this?
return i in {1 + 2}
Expand All@@ -679,7 +679,7 @@ def precomputed(i):
r2 :: bit
r3 :: bool
L0:
r0 = frozenset({(None, (27,)), 1, 1j, 2.7, b'bar', 'daylily', 'foo'})
r0 = frozenset({(), (None, (27,)), 1, 1j, 2.7, False, b'bar', 'daylily', 'foo'})
r1 = PySet_Contains(r0, i)
r2 = r1 >= 0 :: signed
r3 = truncate r1: int32 to builtins.bool
Expand DownExpand Up@@ -718,32 +718,34 @@ def not_precomputed_nested_set(i):
r1 :: object
r2 :: int32
r3 :: bit
r4 :: set
r5 :: int32
r6 :: bit
r7 :: object
r8 :: int32
r9 :: bit
r10 :: object
r11 :: int32
r12 :: bit
r13 :: bool
r4 :: object
r5 :: set
r6 :: int32
r7 :: bit
r8 :: object
r9 :: int32
r10 :: bit
r11 :: object
r12 :: int32
r13 :: bit
r14 :: bool
L0:
r0 = PySet_New(0)
r1 = object 1
r2 = PySet_Add(r0, r1)
r3 = r2 >= 0 :: signed
r4 = PySet_New(0)
r5 = PySet_Add(r4, r0)
r6 = r5 >= 0 :: signed
r7 = object 2
r8 = PySet_Add(r4, r7)
r9 = r8 >= 0 :: signed
r10 = box(int, i)
r11 = PySet_Contains(r4, r10)
r12 = r11 >= 0 :: signed
r13 = truncate r11: int32 to builtins.bool
return r13
r4 = PyFrozenSet_New(r0)
r5 = PySet_New(0)
r6 = PySet_Add(r5, r4)
r7 = r6 >= 0 :: signed
r8 = object 2
r9 = PySet_Add(r5, r8)
r10 = r9 >= 0 :: signed
r11 = box(int, i)
r12 = PySet_Contains(r5, r11)
r13 = r12 >= 0 :: signed
r14 = truncate r12: int32 to builtins.bool
return r14
def not_precomputed_add_operation(i):
i :: int
r0 :: set
Expand Down
6 changes: 3 additions & 3 deletionsmypyc/test-data/run-sets.test
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,10 +123,10 @@ CONST: Final = "CONST"
non_const = "non_const"

def main_set(item: Any) -> bool:
return item in {None, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}
return item in {None,False,1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}

def main_negated_set(item: Any) -> bool:
return item not in {None, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}
return item not in {None,False,1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}

def non_final_name_set(item: Any) -> bool:
return item in {non_const}
Expand All@@ -135,7 +135,7 @@ def non_final_name_set(item: Any) -> bool:
import native
from native import CONST, main_set, main_negated_set, non_final_name_set

for item in (None, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST):
for item in (None,False,1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST):
assert main_set(item), f"{item!r} should be in set_main"
assert not main_negated_set(item), item

Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp