GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||
GeezerVison is showing github.com — gh-87613: Supprt **kwargs in AC VC and use for xml.etree.ElementTree.Element by cmaloney · Pull Request #161597 · python/cpython Conversation
|
| Benchmark | base | Element |
|---|---|---|
| E('a', x='1') | 116 ns | 76.3 ns: 1.52x faster |
| E('a') | 42.6 ns | 28.2 ns: 1.51x faster |
| E('a', attrib=d) | 122 ns | 82.8 ns: 1.47x faster |
| E('a', d) | 73.8 ns | 53.6 ns: 1.38x faster |
| SE(E('p'), 'a', x='1') | 161 ns | 120 ns: 1.35x faster |
| E('a', d, y='2') | 102 ns | 80.3 ns: 1.27x faster |
| S('a') | 49.4 ns | 39.8 ns: 1.24x faster |
Benchmark code:
import pyperf runner = pyperf.Runner() setup = ("from _elementtree import Element as E, SubElement as SE\n" "d = {'x': '1'}\n" "class S(E): pass") for stmt in ["E('a')", "E('a', d)", "E('a', x='1')", "E('a', d, y='2')", "E('a', attrib=d)", "S('a')", "SE(E('p'), 'a', x='1')"]: runner.timeit(stmt, stmt, setup)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
`@vectorcall` with `**kwargs` always delegated to the keyword helper, which only reads a kwargs dict, so it couldn't be generated. The vectorcall now parses positionals with the shared positional emitter and builds the dict from kwnames only when there are keywords, otherwise passing NULL, as the tuple parser does. The `*args` and `**kwargs` parsers take the calling convention explicitly rather than reading `self.fastcall`, which describes the Python-visible entry point having stack style args, not the vectorcall. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ree.Element
xml.etree.ElementTree.Element gains a generated vectorcall. Keys that
are not strings in `**extra` now raise TypeError on a normal call, as
the Python implementation already did, because vectorcall keywords must
be strings; an explicit `__init__` call and subclasses still accept them.
`@text_signature` keeps the documented `(tag, /, attrib={}, **extra)`:
`attrib` can still be passed by keyword, which the impl pops from `extra`.
Merging the keywords into the attributes now copies them with
PyDict_Copy() instead of PyDict_New() plus PyDict_Update(), and pops
`attrib` with `_Py_ID(attrib)` rather than creating a string per call;
SubElement shares that helper.
pyperf microbenchmark (PGO+LTO, run serially):
| Benchmark | base | Element |
|------------------------|:-------:|:---------------------:|
| E('a', x='1') | 116 ns | 76.3 ns: 1.52x faster |
| E('a') | 42.6 ns | 28.2 ns: 1.51x faster |
| E('a', attrib=d) | 122 ns | 82.8 ns: 1.47x faster |
| E('a', d) | 73.8 ns | 53.6 ns: 1.38x faster |
| SE(E('p'), 'a', x='1') | 161 ns | 120 ns: 1.35x faster |
| E('a', d, y='2') | 102 ns | 80.3 ns: 1.27x faster |
| S('a') | 49.4 ns | 39.8 ns: 1.24x faster |
Benchmark code:
```python
import pyperf
runner = pyperf.Runner()
setup = ("from _elementtree import Element as E, SubElement as SE\n"
"d = {'x': '1'}\n"
"class S(E): pass")
for stmt in ["E('a')", "E('a', d)", "E('a', x='1')", "E('a', d, y='2')",
"E('a', attrib=d)", "S('a')", "SE(E('p'), 'a', x='1')"]:
runner.timeit(stmt, stmt, setup)
```
Co-Authored-By: Claude Opus 5.5 <[email protected]>
…eywords Co-Authored-By: Claude Opus 5.5 <[email protected]>
`*args as name` already set the C name; `**kwargs as name` failed to parse because the 'as' regex only allowed a single leading star. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.