Repository navigation
Avoid temporary varargs tuple creation in argument passing #90370
Description
Activity
colorfulappl commented
on Dec 31, 2021 colorfulapplmannequinMannequinAuthorMore actionsWhen "Augument Clinic generated code" are parsing arguments, the args are packed to a tuple before passing to callee. This may be unnecessary.
Pass a raw pointer which points to on-stack varargs, and a varargssize integer to indicate how many varargs are passed, can save the time of tuple creation/destruction and value copy.
- added3.11only security fixesonly security fixesperformancePerformance or resource usagePerformance or resource usage
on Dec 31, 2021 colorfulappl commented
on Dec 31, 2021 colorfulapplmannequinMannequinAuthorMore actionsI wrote some microbenchs.
Patch: b68176d
Environment:
macOS 12.1
clang 13.0.0
configure with --enable-optimizationsResult on microbench:
+--------------------------------------------+-------------------------+------------------------+ | Benchmark | ./opt_baseline/res.json | ./opt_patched/res.json | +============================================+=========================+========================+ | print(a, b, c) | 917 ns | 820 ns: 1.12x faster | +--------------------------------------------+-------------------------+------------------------+ | print(a, b, c, *v) | 1.56 us | 1.62 us: 1.04x slower | +--------------------------------------------+-------------------------+------------------------+ | print(a, sep='', file=stdout) | 376 ns | 295 ns: 1.27x faster | +--------------------------------------------+-------------------------+------------------------+ | print(*v, sep='', flush=True, file=stdout) | 2.02 us | 1.94 us: 1.04x faster | +--------------------------------------------+-------------------------+------------------------+ | Geometric mean | (ref) | 1.05x faster | +--------------------------------------------+-------------------------+------------------------+ Benchmark hidden because not significant (3): print(a), print(a, sep='', flush=True, file=stdout), print(a, b, c, *v, sep='', flush=True, file=stdout)Note that _PyArg_UnpackKeywordsWithVararg is defined with PyAPI_FUNC. Changing its argument spec is strictly a backwards incompatible change, IIUC.
colorfulappl commented
on Jan 4, 2022 colorfulapplmannequinMannequinAuthorMore actionsI am a rookie in Python, did not notice changing PyAPI_FUNC means breaking backward compatibility.
I have reverted _PyArg_UnpackKeywordsWithVararg and committed again.
Note that _PyArg_UnpackKeywordsWithVararg is defined with PyAPI_FUNC. Changing its argument spec is strictly a backwards incompatible change, IIUC.
AFAIK we have committed _PyArg_UnpackKeywordsWithVararg on 3.11 alpha, so I think it should be fine. Also CC: @pablogsal
AFAIK we have committed _PyArg_UnpackKeywordsWithVararg on 3.11 alpha, so I think it should be fine.
I see, so no ABI worries then.
- added3.12only security fixesonly security fixesand removed3.11only security fixesonly security fixes
on Sep 7, 2022 9 remaining items
@erlend-aasland, I'm not sure we can mark this a fixed issue.
The merged pr covers only part of the original proposal (e.g. it doesn't work for the OP example with print()).
Reacted by Erlend E. AaslandI planned to came to this issue in few steps:
- Current gh-122943: Rework support of var-positional parameter in Argument Clinic #122945.
- Move the code for var-positional parameter to a separate converter (this is not easy, because it needs more parameters).
- Split that converter into two converters -- 'tuple' and 'array' to support different representations.
There may be other intermediate steps. I tried to do this in one step, but it was too complicated.
Now, #126064 created conflicts with #122945. I spent a day for this, and see a light at the end of tunnel, but the simplest way to resolve conflict is to revert #126064. Then merge #122945, then continue the initial plan. This will take a time.
Alternatively, I can fuse all these steps in #122945, but the result will be larger and very dirty, because I would need to use dirty tricks like using globals to pass values of local variables between function calls in three or four different modules.
Reacted by Erlend E. AaslandReverting #126064 will also mean reverting #126235. Are there any others that would need reverting, @skirpichev?
Not necessary. Reverting #126064 will just introduce some performance regression for converted functions. But as @serhiy-storchaka planned to address this issue In The Right Way - this will be eventually fixed.
Are there any others that would need reverting
None, as far as I know.
Reacted by Erlend E. AaslandSounds good. Serhiy, please go ahead.
(Given the size (few lines) of #126064, I don't see big problem to resolve merge conflicts. I'll try to do this. Serhiy, feel free to ignore these efforts.)
(Given the size (few lines) of #126064, I don't see big problem to resolve merge conflicts. I'll try to do this. Serhiy, feel free to ignore these efforts.)
IMO, this would be the best option; if we can avoid the revert churn that would be great.
So, if this is not urgent, give me a day.
Thanks, @colorfulappl, for the proposal and initial work; thanks Serhiy and Sergey for the PRs 🍰 👏 🥳
- added a commit that references this issue
on Dec 8, 2024
varargstuple creation in argument passing #30312Note: 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:
bugs.python.org fields:
Linked PRs