This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2016年09月29日 08:49 by serhiy.storchaka, last changed 2022年04月11日 14:58 by admin.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 5012 | merged | serhiy.storchaka, 2017年12月26日 00:04 | |
| PR 26160 | open | serhiy.storchaka, 2021年05月16日 11:30 | |
| PR 26318 | merged | serhiy.storchaka, 2021年05月23日 13:40 | |
| Messages (9) | |||
|---|---|---|---|
| msg277688 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2016年09月29日 08:49 | |
For now using formatted string literals (PEP498) is the fastest way of formatting strings. $ ./python -m perf timeit -s 'k = "foo"; v = "bar"' -- '"%s = %r" % (k, v)' Median +- std dev: 2.27 us +- 0.20 us $ ./python -m perf timeit -s 'k = "foo"; v = "bar"' -- 'f"{k!s} = {v!r}"' Median +- std dev: 1.09 us +- 0.08 us The compiler could translate C-style formatting with literal format string to the equivalent formatted string literal. The code '%s = %r' % (k, v) could be translated to t1 = k; t2 = v; f'{t1!r} = {t2!s}'; del t1, t2 or even simpler if k and v are initialized local variables. $ ./python -m perf timeit -s 'k = "foo"; v = "bar"' -- 't1 = k; t2 = v; f"{t1!s} = {t2!r}"; del t1, t2' Median +- std dev: 1.22 us +- 0.05 us This is not easy issue and needs first implementing the AST optimizer. |
|||
| msg277694 - (view) | Author: Eric V. Smith (eric.smith) * (Python committer) | Date: 2016年09月29日 09:42 | |
There isn't a direct mapping between %-formatting and __format__ format specifiers. Off the top of my head, I can think of at least one difference:
>>> '%i' % 3
'3'
>>> '{:i}'.format(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'i' for object of type 'int'
So you'll need to be careful with edge cases like this.
Also, for all usages of %s, remember to call str() (or add !s):
>>> '%s' % 1
'1'
>>> f'{1:s}'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'int'
>>> f'{1!s:s}'
'1'
Although that also reminds me of this default alignment difference:
>>> x=0
>>> '%2s' % x
' 0'
>>> f'{x!s:2s}'
'0 '
>>> f'{x!s:>2s}'
' 0'
So, in general, the mapping will be difficult. On the other hand, if you can do it, and provide a function that maps between %-formatting codes and __format__ codes, then that might be a generally useful tool.
|
|||
| msg277700 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2016年09月29日 10:44 | |
'%s' % x should be translated to f'{x!s}', not to f'{x:s}'. Only %s, %r and %a can be supported. Formatting with %i should left untranslated. Or maybe translate '%r: %i' % (a, x) to f'{a!r}: {"%i" % x}'.
It is possible also to introduce special opcodes that converts argument to exact int or float. Then '%06i' % x could be translated to f'{__exact_int__(x):06}'.
|
|||
| msg277702 - (view) | Author: Antti Haapala (ztane) * | Date: 2016年09月29日 12:01 | |
Serhiy, you actually did make a mistake above; `'%s' % x` cannot be rewritten as `f'{x!s}'`, only `'%s' % (x,)` can be optimized...
(just try with `x = 1, 2`)
|
|||
| msg277703 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2016年09月29日 12:40 | |
Thanks for the correction Antti. Yes, this is what I initially meant. This optimization is applicable only if the left argument of % is a literal string and the right argument is a tuple expression. Saying about `'%s' % x` I meant a component of the tuple. |
|||
| msg309049 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2017年12月26日 00:07 | |
PR 5012 implements transformation simple format strings containing only %s, %r and %a into f-strings. |
|||
| msg324795 - (view) | Author: Tal Einat (taleinat) * (Python committer) | Date: 2018年09月07日 21:15 | |
I'm +1 on this optimization. |
|||
| msg393740 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2021年05月16日 11:50 | |
PR 26160 adds support of %d, %i, %u, %o, %x, %X, %f, %e, %g, %F, %E, %G. What is not supported: * Formatting with a single value not wrapped into a 1-tuple (like in "%d bytes" % size). The behavior is non-trivial, it needs checking whether the value is a tuple or a mapping. It would require adding more opcodes and AST nodes and generating complex bytecode. * Mapping keys (like in "%(name)s"). They are rarely used, and if used, it is not performance critical. * Precision for integer formatting. Precision is not supported in new-style formatting of integers, and it is not trivial to reproduce this behavior. * Variable width and precision (like in "%*.*s"). It is possible to support them, but the code would be pretty complex, and the benefit is small, because this feature is rarely used and is not performance critical. * Format code %c. It is relatively rarely used. * Length modifiers "h", "l" and "L" (like in "%ld"). They ignored in Python and I did not see them in real code. While supporting them is easy, it would requires adding more than one line of code, it is not worth it. |
|||
| msg402436 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2021年09月22日 13:56 | |
commit a0bd9e9c11f5f52c7ddd19144c8230da016b53c6 Author: Serhiy Storchaka <storchaka@gmail.com> Date: Sat May 8 22:33:10 2021 +0300 bpo-28307: Convert simple C-style formatting with literal format into f-string. (GH-5012) C-style formatting with literal format containing only format codes %s, %r and %a (with optional width, precision and alignment) will be converted to an equivalent f-string expression. It can speed up formatting more than 2 times by eliminating runtime parsing of the format string and creating temporary tuple. commit 8b010673185d36d13e69e5bf7d902a0b3fa63051 Author: Serhiy Storchaka <storchaka@gmail.com> Date: Sun May 23 19:06:48 2021 +0300 bpo-28307: Tests and fixes for optimization of C-style formatting (GH-26318) Fix errors: * "%10.s" should be equal to "%10.0s", not "%10s". * Tuples with starred expressions caused a SyntaxError. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:37 | admin | set | github: 72494 |
| 2021年09月22日 13:56:33 | vstinner | set | nosy:
+ vstinner messages: + msg402436 |
| 2021年05月23日 13:40:03 | serhiy.storchaka | set | pull_requests: + pull_request24913 |
| 2021年05月19日 22:21:33 | brandtbucher | set | nosy:
+ brandtbucher |
| 2021年05月16日 11:50:56 | serhiy.storchaka | set | priority: low -> normal messages: + msg393740 |
| 2021年05月16日 11:31:21 | serhiy.storchaka | set | nosy:
+ Mark.Shannon versions: + Python 3.11, - Python 3.7 |
| 2021年05月16日 11:30:17 | serhiy.storchaka | set | pull_requests: + pull_request24794 |
| 2018年09月07日 21:15:06 | taleinat | set | nosy:
+ taleinat messages: + msg324795 |
| 2017年12月26日 00:07:35 | serhiy.storchaka | set | messages: + msg309049 |
| 2017年12月26日 00:04:15 | serhiy.storchaka | set | keywords:
+ patch stage: patch review pull_requests: + pull_request4901 |
| 2017年12月25日 16:57:34 | serhiy.storchaka | set | assignee: serhiy.storchaka |
| 2016年09月29日 12:40:20 | serhiy.storchaka | set | messages: + msg277703 |
| 2016年09月29日 12:01:36 | ztane | set | nosy:
+ ztane messages: + msg277702 |
| 2016年09月29日 10:44:19 | serhiy.storchaka | set | messages: + msg277700 |
| 2016年09月29日 09:42:27 | eric.smith | set | messages: + msg277694 |
| 2016年09月29日 08:50:19 | serhiy.storchaka | set | dependencies: + Build-out an AST optimizer, moving some functionality out of the peephole optimizer |
| 2016年09月29日 08:49:56 | serhiy.storchaka | create | |