Skip to content

Commit eb1c525

Browse files
[mypyc] Faster int conversion in str.format (#10774)
Closes mypyc/mypyc#875
1 parent cdb2685 commit eb1c525

File tree

3 files changed

+35
-36
lines changed

3 files changed

+35
-36
lines changed

mypyc/irbuild/specialize.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
)
2626
from mypyc.ir.rtypes import (
2727
RType, RTuple, str_rprimitive, list_rprimitive, dict_rprimitive, set_rprimitive,
28-
bool_rprimitive, is_dict_rprimitive, c_int_rprimitive, is_str_rprimitive,
29-
c_pyssize_t_rprimitive
28+
bool_rprimitive, c_int_rprimitive, c_pyssize_t_rprimitive, is_dict_rprimitive,
29+
is_int_rprimitive, is_str_rprimitive, is_short_int_rprimitive
3030
)
31+
from mypyc.primitives.int_ops import int_to_str_op
3132
from mypyc.primitives.dict_ops import (
3233
dict_keys_op, dict_values_op, dict_items_op, dict_setdefault_spec_init_op
3334
)
@@ -373,9 +374,17 @@ def translate_str_format(
373374

374375
literals = split_braces(format_str)
375376

376-
variables = [builder.accept(x) if is_str_rprimitive(builder.node_type(x))
377-
else builder.call_c(str_op, [builder.accept(x)], expr.line)
378-
for x in expr.args]
377+
# Convert variables to strings
378+
variables = []
379+
for x in expr.args:
380+
node_type = builder.node_type(x)
381+
if is_str_rprimitive(node_type):
382+
var_str = builder.accept(x)
383+
elif is_int_rprimitive(node_type) or is_short_int_rprimitive(node_type):
384+
var_str = builder.call_c(int_to_str_op, [builder.accept(x)], expr.line)
385+
else:
386+
var_str = builder.call_c(str_op, [builder.accept(x)], expr.line)
387+
variables.append(var_str)
379388

380389
# The first parameter is the total size of the following PyObject* merged from
381390
# two lists alternatively.

mypyc/primitives/int_ops.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
error_kind=ERR_MAGIC)
5454

5555
# str(n) on ints
56-
function_op(
56+
int_to_str_op = function_op(
5757
name='builtins.str',
5858
arg_types=[int_rprimitive],
5959
return_type=str_rprimitive,

mypyc/test-data/irbuild-str.test

+20-30
Original file line numberDiff line numberDiff line change
@@ -169,35 +169,25 @@ def f(s: str, num: int) -> None:
169169
def f(s, num):
170170
s :: str
171171
num :: int
172-
r0 :: object
173-
r1, r2, r3, r4, r5, s1, r6, s2, r7, s3 :: str
174-
r8 :: object
175-
r9 :: str
176-
r10 :: object
177-
r11 :: str
178-
r12 :: object
179-
r13, r14, r15, r16, r17 :: str
172+
r0, r1, r2, r3, r4, s1, r5, s2, r6, s3, r7, r8, r9, r10, r11, r12, r13 :: str
180173
L0:
181-
r0 = box(int, num)
182-
r1 = PyObject_Str(r0)
183-
r2 = "Hi! I'm "
184-
r3 = ", and I'm "
185-
r4 = ' years old.'
186-
r5 = CPyStr_Build(5, r2, s, r3, r1, r4)
187-
s1 = r5
188-
r6 = ''
189-
s2 = r6
190-
r7 = 'abc'
191-
s3 = r7
192-
r8 = box(int, num)
193-
r9 = PyObject_Str(r8)
194-
r10 = box(int, num)
195-
r11 = PyObject_Str(r10)
196-
r12 = box(int, num)
197-
r13 = PyObject_Str(r12)
198-
r14 = '}'
199-
r15 = '{'
200-
r16 = '}{'
201-
r17 = CPyStr_Build(6, r14, r9, r15, r11, r16, r13)
202-
s3 = r17
174+
r0 = CPyTagged_Str(num)
175+
r1 = "Hi! I'm "
176+
r2 = ", and I'm "
177+
r3 = ' years old.'
178+
r4 = CPyStr_Build(5, r1, s, r2, r0, r3)
179+
s1 = r4
180+
r5 = ''
181+
s2 = r5
182+
r6 = 'abc'
183+
s3 = r6
184+
r7 = CPyTagged_Str(num)
185+
r8 = CPyTagged_Str(num)
186+
r9 = CPyTagged_Str(num)
187+
r10 = '}'
188+
r11 = '{'
189+
r12 = '}{'
190+
r13 = CPyStr_Build(6, r10, r7, r11, r8, r12, r9)
191+
s3 = r13
203192
return 1
193+

0 commit comments

Comments
 (0)