#๐ Why is Python3.13 slower? How do I fix it?
157 messages ยท Page 1 of 1 (latest)
@crude smelt
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
If you have a benchmark, you should report an issue to cpython
It's still in beta after all
It's a release candidate now.
it's still in rc after all
Yes, but this is the second to last rc and I'm worried.
I've been holding off saying that since early betas.
!paste don't upload text files
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
python3.12 performance-test.py 16.95s user 0.24s system 96% cpu 17.728 total
python3.13 performance-test.py 20.45s user 0.25s system 95% cpu 21.661 total
And the code you ran?
Way to long to paste here.
!pastebin
^^^
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
It's like 20 files
then make a git repo
I have one.
Where is the performance-test.py?
In Aardvark-Interpreter
Test it with more versions of python. Which version introduced the regression?
What do you mean?
It was fast in 3.11, even faster in 3.12, and then slow in 3.13
test on different patch versions. i.e. 3.12.4, 3.12.3, etc
also test different 3.13 betas
I'm currently on 3.12.4 and its fast.
I tested beta 2, beta 4, and rc 1.
Beta 2 was bad, but not quite this bad iirc. Beta 4 was this bad (maybe 5% worse than beta 2), and rc1 is what I showed the results for.
How are you installing/compiling Python?
I don't know. It seems that len takes longer in 3.13, and this function:
def detect(self, text):
i = 0
for char in text:
if self.peek(i) != char:
return False
i += 1
return True
Took significantly longer in 3.13 than 3.12.4
len takes a decent amount longer, but not that much.
!pep 703 probably related to this
It says there's an option to reenable it
3.13rc1 just default install from python.org
The GIL is still enabled by default in 3.13
Hm....
can you find some minimal example that exhibits the behavior?
What class is detect from? I want to check it in Linux and Windows x86
if it is len of something that it an issue getting an example shouldn't be hard
class Lexer in Aardvark-Interpreter/Lexer.py
I can try I guess.
Maybe faster-cpython benchmarks need to be updated. https://github.com/faster-cpython/benchmarking-public
did you configure with --with-lto and whatnot
I guess its just my specific use cases, but its really harming my program's performance.
No... What is that?
They used the python.org installer
So itโll be using whatever flags the release manager decided to build the release with
It's probably worth reporting a bug to CPython for this, especially if you can isolate your benchmark code to a specific isolated sample that runs slower in 3.13 than 3.12
Okay. I see a lot of functions run slower and some run faster. I may need to try to see if I can find anything in common there.
Write the issue first with the details you have now.
i'm wondering if the RC has optimizations disabled
Are you running this in pure Python or cythonized?
If you're using CProfile specifically, some of the changes may also be due to changes in how monitoring and reporting work; I think that's changed a lot
Though Ned would know more about that
it shouldnโt
Pure python
Same issue without CProfile
CProfile was just to help find the issue.
Great, let me run some timings then.
I have to go now, but I'll check back here later and see about writing up an issue.
i'm going to build it manually and run some benchmarks
Let me double check this to see if there's a difference
Make sure your CPU isnโt busy with anything else as well, that can significantly skew results
Without CProfile:
python3.12 Aardvark\ Interpreter/performance-test.py 6.09s user 0.16s system 98% cpu 6.468 total
python3.13 Aardvark\ Interpreter/performance-test.py 7.34s user 0.17s system 95% cpu 7.619 total
Yeah, I've tested under various conditions. It's all reproducible.
For reference, this was with CProfile
About the same ratio
Be back later
3.13 was slightly faster on Windows, slight enough to be noise, running performance-test.py
Oh, it's beta4. Let me check RC1
oh damn it, i just built beta 4
Might it be a issue with optimization of the macOS binary, or somehow running the x86 code instead of Arm?
running performance-test.py on x86 gave no real difference between 3.12 and 3.13
Is this beta 4?
no, RC1 built locally
3.13 seems to be slightly faster than 3.12, based on these benchmarks
Same, on Windows. I just realized I don't want to build with PGO so I will skip testing on Linux ๐คทโโ๏ธ
Does the macOS build use ./configure and make? If so, sysconfig.get_config_var('OPT') might give a clue.
sysconfig.get_config_var('CONFIG_ARGS') might also help, if it works
'-DNDEBUG -g -O3 -Wall'
I am on ARM; I listed both hardware and software in the original message.
i know, my guess is that the slowdown is ARM-related
It's still an issue though
looks like it could be. file a bug report on cpython
I plan to. Except I still don't know the root cause or what exactly makes it slower.
if you could send the logs from cProfile, then you can see what function is taking longer
Is that for both 3.13 and 3.12?
Well, its a lot of them
That's for 3.13rc1
How's 3.12?
that's why we have a pastebin
I already sent the CProfile pastebin above
"Except": you don't need to know the cause to write an issue.
oh, i didn't see that
3.12 is "'-C' '--enable-framework' '--enable-universalsdk=/' '--with-universal-archs=universal2' '--with-computed-gotos' '--without-ensurepip' '--with-openssl=/tmp/_py/libraries/usr/local' '--enable-optimizations' '--with-lto' 'TCLTK_CFLAGS=-I/tmp/_py/libraries/usr/local/include' 'TCLTK_LIBS=-ltcl8.6 -ltk8.6' 'LDFLAGS=-g' 'CFLAGS=-g' 'CC=clang'"
oh
That could be part of the issue right there.
i think they forgot to enable optimizations for that build
I guess so. But would that account for 25%??
yes
Okay, then I guess we found our problem
Are you sure you're comparing the same var? "OPT" versus "OPT" or "CONFIG_ARGS" versus "CONFIG_ARGS"?
Oh, maybe not.
I just copied without paying attention. Let me look...
Oh, yeah, I did different ones
OPT:
3.13rc1: -DNDEBUG -g -O3 -Wall
3.12.4: -DNDEBUG -g -O3 -Wall
CONFIG_ARGS:
3.13rc1: '--enable-framework' '--with-framework-name=Python' '--enable-universalsdk=/' '--with-universal-archs=universal2' '--enable-optimizations' '--with-lto' '--without-ensurepip' '--with-system-libmpdec' '--with-openssl=/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local' 'LIBLZMA_CFLAGS=-I/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/include' 'LIBLZMA_LIBS=-L/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/lib -llzma' 'LIBMPDEC_CFLAGS=-I/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/include' 'LIBMPDEC_LIBS=-L/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/lib -lmpdec -lm' 'LIBSQLITE3_CFLAGS=-I/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/include' 'LIBSQLITE3_LIBS=-L/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/lib -lsqlite3' 'TCLTK_CFLAGS=-I/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/include' 'TCLTK_LIBS=-L/Users/nad/release-tools/macos-installer/installer/variant/binaries/build/libraries/usr/local/lib -ltcl -ltk' 'CC=clang'
3.12.4: '-C' '--enable-framework' '--enable-universalsdk=/' '--with-universal-archs=universal2' '--with-computed-gotos' '--without-ensurepip' '--with-openssl=/tmp/_py/libraries/usr/local' '--enable-optimizations' '--with-lto' 'TCLTK_CFLAGS=-I/tmp/_py/libraries/usr/local/include' 'TCLTK_LIBS=-ltcl8.6 -ltk8.6' 'LDFLAGS=-g' 'CFLAGS=-g' 'CC=clang'
ok, so they both are compiled with optimizations, odd
Okay, then it must be a different issue.
could you come up with a reproducer that runs slower on 3.13
how much difference do computed gotos make? that's one flag that seems to be different unless that's on by default
if this is a difference it could explain a good chunk of the diff
Comments inside the CPython implementation note that using computed goto made the Python VM 15-20% faster
That could be it.
considering it depends on a compiler extension it might not be the default, should be easy to check for someone who knows the python build setup (i.e. not me)
I'll make a build with that turned on to check
Just checked, it's supposed to have computed gotos even without the config option, it's enabled by defauld on mac
So, I don't need to build and check?
I say build it and see how it behaves ๐
What all options should I use?
I don't know the mac build system, I have doubts about framework and universal stuff. Let me check the devguide.
This is my first time ever building from source.
Should I still build from source? I've never done this before.
Erm, it might not be worth it then.
Okay
Let me give you a small reproducer, if it shows the slowdown it should help filing an issue.
from time import process_time
class Lexer:
def __init__(self, data):
self.data = data
self.index = 0
def detect(self, text):
i = 0
for char in text:
if self.peek(i) != char:
return False
i += 1
return True
def peek(self, amt=1):
if self.index + amt < len(self.data):
return self.data[self.index + amt]
else:
return None
text = "return text + indent * ' ' + '}'\n" * 200
needle = "return text + indent * ' ' + '}'\n" * 199 + "Nope\n"
lexer = Lexer(text)
start = process_time()
for x in range(100):
lexer.detect(needle)
print(process_time() - start)
Please see if this is enough to show the slowdown. Adjust the numbers so it runs for a couple seconds.
I ran the test multiple times, and yes, on average there is a small slow down.
switch the loop to like 10000 if the slowdown is too miniscule
10,000 Repetitions:
3.12.4: 7.742122s
3.13rc1: 8.309326s
can you try building 3.12.4 from source, the same way as you're building 3.13rc1, and seeing how the two builds compare?
that makes sure that you're doing an apples-to-apples comparison: the same build options used to build both interpreters, on the same machine, with the same compiler, etc
I didn't end up building it from source.
This is the config
oh, then I misunderstood
I didn't realize python.org has pre-built macOS binaries for the beta releases. TIL
3.13 is consistently faster than 3.12 for me on Windows x86 with that reproducer.
It seems to be a bug specific to Mac.
Anyone tested on linux ARM?
Not yet, that I know of.
I don't have it so I didn't.
I created an Issue:
https://github.com/python/cpython/issues/122580
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.