The bytecode for f-string formatting is inefficient. #77273
Copy link
Copy link
Closed
Labels
3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usage
Description
| BPO | 33092 |
|---|---|
| Nosy | @pitrou, @ericvsmith, @markshannon, @serhiy-storchaka |
| PRs |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2018-03-17.12:33:10.371>
labels = ['interpreter-core', '3.8', 'performance']
title = 'The bytecode for f-string formatting is inefficient.'
updated_at = <Date 2021-08-26.14:31:11.408>
user = 'https://github.com/markshannon'bugs.python.org fields:
activity = <Date 2021-08-26.14:31:11.408>
actor = 'Mark.Shannon'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2018-03-17.12:33:10.371>
creator = 'Mark.Shannon'
dependencies = []
files = []
hgrepos = []
issue_num = 33092
keywords = ['patch']
message_count = 7.0
messages = ['314000', '314001', '314004', '314312', '314317', '322379', '400348']
nosy_count = 4.0
nosy_names = ['pitrou', 'eric.smith', 'Mark.Shannon', 'serhiy.storchaka']
pr_nums = ['6132']
priority = 'normal'
resolution = None
stage = 'patch review'
status = 'open'
superseder = None
type = 'performance'
url = 'https://bugs.python.org/issue33092'
versions = ['Python 3.8']Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usage
Activity
markshannon commentedon Mar 17, 2018
f-string expressions can be formatted in four ways:
with or without a conversion
and
with or without a format specifier
Rather than have one bytecode that parses the opcode argument at runtime it would be more efficient and produce a cleaner interpreter for the compiler to produce one or two bytecode as required.
The bytecodes should be:
CONVERT_VALUE convert_fn
FORMAT_SIMPLE
FORMAT_WITH_SPEC
For simple format expressions with no conversion or format specifier,
which make up about 3/4 of all format expressions in the standard library, just the bytecode FORMAT_SIMPLE need be executed.
ericvsmith commentedon Mar 17, 2018
Would this change really have a performance impact? Not saying it wouldn't, but if we're going to add bytecodes we should know the answer in advance.
markshannon commentedon Mar 17, 2018
Even if doesn't speed things up by a significant amount, I would suggest that a simper interpreter with smaller, simpler bytecodes is a worthy goal in itself.
pitrou commentedon Mar 23, 2018
+1 from me. Though I'm curious about performance changes as well :-)
serhiy-storchaka commentedon Mar 23, 2018
I wouldn't say this more efficient. Instead one instruction you would need to execute two instructions.
If I implemented f-string formatting I would add four simple opcodes for str(), repr(), ascii() and format(). But Eric merged them all in the single opcode with complex argument. While this looks more complicated and less extensible, it is more efficient.
taleinat commentedon Jul 25, 2018
Mark, since you have a working version of this, perhaps you can supply some performance benchmark results to help in making a decision?
markshannon commentedon Aug 26, 2021
No significant change in performance https://gist.github.com/markshannon/34a780d65e69b5a573a83f3fdb0139aa
I think this merely indicates that there are little to no f-strings in the pyperformance benchmark suite.
iritkatriel commentedon Sep 1, 2022
@markshannon are you still interested in this? should we repeat the measurements with benchmarks that have more f-strings?
GH-77273: Better bytecodes for f-strings (GH-6132)
Merge branch 'main' into modulelocals
hauntsaninja commentedon Sep 7, 2023
Looks like this was implemented in #6132, thanks all!