How Fast is Python 3.15?

(blog.miguelgrinberg.com)

64 points | by Qem 11 hours ago ago

49 comments

  • jakobnissen 3 hours ago ago

    So not much progress since 3.14 - but still progress! Personally, I think it's nice when my code automatically gets faster thanks to someone else's work, and I don't understand all the negative sentiment in this thread. Yes, of course Python is still a slow language. You hopefully knew that when you picked Python for your project.

    • scorpioxy 2 hours ago ago

      I tend to describe it as "a language not optimized for raw processing speed" as opposed to being a slow language. As in, it is an abstraction that is meant to speed up development(and be easier to read etc) rather than be the fastest while running.

      • BerislavLopac 25 minutes ago ago

        Exactly. I like to say that Python is one of the fastest languages if you measure by metrics other than "raw processing speed". One very important metric is speed of development - and due to a combination of lack of the compilation step, its dynamic nature, ecosystem of libraries and clean syntax, very few languages can match Python in that regard.

  • scosman 6 hours ago ago

    only tangentially related, but naming PyPy when PyPI was already established was ridiculous

    • zahlman 36 minutes ago ago

      Both names have sensible etymology ("Python [implemented in] Python"; "Python Package Index") and are pronounced differently (PyPI is "pie pee eye").

      PyPy dates to 2007 (older than Pip!); back then I'm pretty sure people were still calling PyPI the Cheeseshop, and it was still hosted on the main python.org site for years after that (https://packaging.python.org/en/latest/guides/migrating-to-p...).

  • makaimc 9 hours ago ago

    35 years on since the first public Python release and there's still so much room for improvement in its performance. These tests by Miguel are a useful quick check on that progress in 3.15 even if as he admits it's impossible to get "an objective and universal measure of the performance of a programming language".

  • dezsiszabi 5 hours ago ago

    Answer: not fast at all.

    • keyle 3 hours ago ago

      I'd go one step further: was never fast and can never be fast.

  • brianwawok 9 hours ago ago

    So Claude can convert python code bases to rust or golang, and give you an easy 10x speed boost. Much better than waiting for Python performance to improve

    • nomel 6 hours ago ago

      Yeah, none of these tight loop benchmark tasks should be happening in python, which is why you won't see anywhere NEAR this kind of speedup with "normal" python code, that makes any attempt to use the many c python libraries that exists for these (like the built in sort functions, ffs).

      Over the years, I've tried pypy and whatnot, but I've only ever seen between -30% and 30% speedups, depending on the code.

    • ks2048 9 hours ago ago

      For a lot of scripts (think replacement to bash scripts - perhaps even one-offs), Python will save time over rust compilation times.

      • nazcan 9 hours ago ago

        Golang it is then! I'm really enjoying the fast compile time compared to C++...

        • skrtskrt 7 hours ago ago

          And packaging + distribution is ridiculously easy.

          We are moving every script we can to Go. Compared to bash it's a no-brainer, every dev can understand it, it has approximately .0000000000001% of the possible footguns, a great debugger, etc.

      • masklinn 3 hours ago ago

        At the scale of “bash scripts”, rust will compile instantly unless you’ve gone insane with dependencies

      • cogman10 8 hours ago ago

        For one offs, sure. But once you get to a script executed multiple times it doesn't take very long before you have payed off the rust compile time. Especially if it is fairly simple (as in, you can do everything with just rust std lib and not a bunch of rust libs).

        Almost all the rust compilation times come from needing to build the supporting libs. For simple scripts, it's very possible to get away with just using the std lib.

        • UnlockedSecrets 8 hours ago ago

          At the same time, If a python script can be thrown together in 20 minutes, and it will execute hundreds of times at most..... Who really cares if it takes 25 seconds to execute, or 2 minutes as long as it accomplishes all it is intended to do?

          • cogman10 8 hours ago ago

            In my opinion, what is pretty typical a script will be executed never, once, or thousands of times.

            If you are at the point of doing multiple executions, you are probably at the point where converting your script to rust would end up saving time/power. Maybe not all the time (like a manually executed script), but not infrequently.

      • pjmlp 3 hours ago ago

        There are D, Go, C#, OCaml as an option, not only Rust.

      • loeg 8 hours ago ago

        Non-optimized builds can be pretty quick, although I guess you're always paying for borrow checking.

        • masklinn 3 hours ago ago

          Being a local property, borrow checking is cheap. IIRC even Polonius is single digit percent in the worst case on crater runs.

    • sgarland 9 hours ago ago

      There is a benefit in being able to read and understand your code. If you’re most proficient in Python, it’s reasonable to want to stay there, perhaps looking to PyPy.

      Also, of course, the majority of SaaS apps (perhaps most apps in general?) are not compute-bound, so gains from performance alone shouldn’t be the only metric.

      My current job has a mix of Python and Go. Personally, I dislike Go. I don’t like its syntax, I don’t like its utter lack of formatting standards (gofmt is not a standard; also it sets tabs - ugh), I don’t like its insistence on static linking, and I don’t like how people claim it’s a great scripting language when you can’t just run a file on its own (and its stdlib is weak sauce compared to Python).

      • killingtime74 7 hours ago ago

        I can read rust much easier than go at least. If the Python doesn't have types then it's about even as well.

      • loeg 8 hours ago ago

        Of course, Claude understands Rust, too.

      • winrid 7 hours ago ago

        Rust is nice to read because you can see from a function signature what it mutates

        If you write slow rust, it's very easy to read, and still plenty fast.

        • rtpg 5 hours ago ago

          For a server using a DB, all of your methods are calling out to data stores. So you're like "OK I receive a &connection" but all the mutability is hidden inside.

          There's a bunch of type direction you can do to get around this (`ReadConnection` vs `ReadWriteConnection` and some other magic), far from an immediate win but it's not impossible.

          People talk about mutability a lot but the vast majority of Python code I see in the wild is SSA and has _very_ little mutability to begin with.

          Of course ownership still has its costs. Lots of "I guess I'm copying this dict because I don't know if the owner will modify it or not" issues.

          I think people overestimate how much they'll get from `&mut` annotations on business logic, and undersestimate how much line noise they'd get from a lot of the other stuff that happens in a lot of business logic.

          Granted, I'm coming from a web-dev/Django perspective, where duck typing and overriding methods in subclasses is used heavily. And a lot of that doesn't have a nice 1:1 equivalent in the Rust model.

          (I enjoy Rust BTW, just don't feel particular excitement about shuffling around strings in it)

    • tclancy 7 hours ago ago

      Why not convert to assembly?

      • ChrisRR 42 minutes ago ago

        You mean compiling?

      • chronogram 4 hours ago ago

        Assembly doesn't add anything here. You'd still need to implement the IO, portability, safety, etc etc. You'd end up with the same thing so you might as well use Go from the get go. Assembly is useful for dedicated SIMD like in dav1d.

      • Izikiel43 7 hours ago ago

        Portability

    • pmarreck 3 hours ago ago

      Can’t wait for this to eliminate Python frankly. Too many scars from that unfortunate ecosystem

  • DroneBetter 7 hours ago ago

    you should include a faster version of the fibonacci function with exponentiation by squaring

      def fibonacci(k):
        a,b=(0,1)
        for i in range(k.bit_length()-1,-1,-1):
          d=a**2
          c=2*a*b-d
          d+=b**2
          (a,b)=(d,c+d) if k>>i&1 else (c,d)
        return a
    
    see https://oeis.org/wiki/User:Natalia_L._Skirrow/linear_recurre... (warning: old and bad and in need of revision), https://github.com/sympy/sympy/pull/30452 and https://github.com/sympy/sympy/pull/30541 for details of how to make similarly fast programs for arbitrary linear-recurrent sequences.

    you can also encode polynomials into integers; see https://mathstodon.xyz/@peterluschny/116320199782572958 and the following prog from https://codegolf.stackexchange.com/a/279771

      lambda n:pow(p:=2<<n,n,p*p+~p)//p
    
    both of these would be more intensive on the arithmetic side rather than control flow

    also you could at least wrap the existing one in a `functools.cache`

    • 0123456789ABCDE 3 hours ago ago

      the point of the benchmark is not to make `fib()` fast, but to exercise the code in ways everyone can understand. ex: `functools.cache` decorator would mostly show you how fast python `dict`s are — not very useful

  • klooney 6 hours ago ago

    I had kind of thought PyPy was dead, I'm glad to see they made it to 3.12

  • perpetualpear 3 hours ago ago

    The lazy imports are a reason to upgrade.

  • rurban 8 hours ago ago

    2 benchmarks only? A very broad sense of coverage

  • bjourne 7 hours ago ago

    My pet peeve are numbers with too many decimals. If you only run a benchmark three times and take the arithmetic mean you don't have five or more significant digits. At best, you have two. And for benchmarking the geometric mean is a far superior mean.

    • jrk 7 hours ago ago

      For averaging multiple different benchmarks, the geometric mean makes sense. For removing measurement noise from a single benchmark, min or median is usually the right statistic.

  • sieve 6 hours ago ago

    I have been using Python for the past two years for various things. But it is criminally slow. I joke that using Python on your modern 2020s CPU upgrades it to a Pentium 4 from 2004 running code compiled with C. And the 2004 version might still be faster.

    Yes, some of the syntax is nice. But the rest of it, the scoping rules, the obstinacy around the lambda syntax, the venv/pip nonsense, path resolution etc is a hot mess. Were it not for astral tooling like uv, I would have abandoned it in a few weeks.

    I hate thinking about memory outside of very specific workflows, so I am willing to accept a 2-3x penalty over C for cleaner and shorter code that follows the happy path. But anything beyond that and you are wasting energy and people's time.

    For Python to work as something other than a glue language where we write all critical code in C/Rust and call it from inside Python, something like PyPy is almost mandatory. But the design of the language, the exposed innards, and the need to maintain backward compatibility makes optimization a chore.

    I did some benchmarking of Python against C, Go, Rust, Node, LuaJIT etc in preparation for my runtime.[1] My observations based on some stats:

    - You can blindly replace C with Rust for most tested workflows. There is very little performance difference outside of compiler speed. (C23 is a nice language though.)

    - Go is 2-3x slower than C

    - Node and LuaJIT are 3-8x slower on average compared to C

    - Python is 60-70x slower. It can get far, far slower in certain cases.

    You can run your own benchmarks. I think you might end up in the same ballpark.

    [1] I have been interested in reverse engineering, hobbyist compiler/VM development etc for a couple of decades and wondered what is the point of ranting for two years about it without doing anything concrete. So I decided to build a runtime and statically typed language borrowing stuff from Python and Erlang/BEAM. But, even with LLMs implementing my ideas faithfully, the last 20-30% is a never-ending process which means I get bored and move on to something I can finish in 3-4 days.

    • orojackson 4 hours ago ago

      It also depends on what your use case is for the programs you write in those languages. If the use case relies heavily on CPU performance, then yeah, Python is awful in that regard. But if you're like me who mostly deals with ETL processes and report generation from several different systems over the internet, then Python's 60-70x slowdown means NOTHING in the face of network latency and the need to work with pagination limitations these external systems impose on REST endpoint users (and no, gRPC or its binary-serialization ilk are not available options).

      Outside of that, though, what really grinds my gears about Python aside from its broad standard library compared to other languages is that it is home to what I think is the best property testing library in the world, Hypothesis. I know that the folks at Antithesis are working on getting Hegel [1] up and running, but they don't even have plans to support the language that my workplace prefers: C# (and I have been leading the charge in my workplace to keep up with the latest versions of .NET). Given how agents are now creating and modifying whole codebases, property tests live in that nice middle ground between unit tests and formal verification when it comes to validating (as best as we can) that the code works as intended.

      [1] https://hegel.dev/

      • sieve 3 hours ago ago

        Yes, the workflow matters. And it is one reason why Python is popular in the ETL and other processes. You are essentially offloading computation to efficient code while Python simply orchestrates. You probably spend one percent of the time inside Python itself, so it is pretty convenient.

        I normally have one "tooling" language that I write all kinds of stuff in. And it goes beyond glue. So performance matters to me.

        re: testing, I am pretty old-fashioned. I don't test everything. Only stuff that is critical or complex enough where I suspect breakage in the future. Also, I think borrowing ideas from Ada/Haskell/Clean etc for a new language could solve a lot of these pain points, now that LLMs are writing most of the code.

        • orojackson 2 hours ago ago

          Pretty charitable to call Salesforce a bastion of "efficient code" hahaha

          You're lucky to be able to control as much of the stack as you want with your one "tooling" language to rule them all so that performance matters again. Although in all fairness, given the regulatory and workplace culture as well as constrained budgets, sometimes you do have to let go of chasing performance in the name of making things easier for the maintainers at work. As I mentioned in a different post, it also helps to be working in a captive market, which helps relieve the pressure a bit.

          Also, my Python ETL scripts do calculations for certain things, but attempting to speed that part up with a low level language like C or Rust doesn't really move the needle for total processing time when you have latencies measured in the hundreds of milliseconds per page of data. Scale that up to multiple pages and the whole runtime is dominated by how long it takes for packets to move from my Windows Server to Salesforce and back. It's basically a whole lot of effort for very little gain.

          • sieve an hour ago ago

            Work is JVM. So not much space there. But I did manage to incorporate a tiny LISP-like language into my principal application to make some configuration tasks easier. Everything outside it, I can control.

            I get your usage. If you never spend enough time in slow mode, there is no point moving the code elsewhere as the savings do not justify the labor.

            My issue is that I do not want to use or maintain code in 10 different languages. A single language, even one that is 3-5x slower than C would work. My only asks are that it should:

            - be performant

            - have basic infrastructure (cryptography, database etc)

            - be aesthetically pleasing to read and write

    • mroche 4 hours ago ago

      > I did some benchmarking of Python against C, Go, Rust, Node, LuaJIT etc in preparation for my runtime.

      Out of curiosity, have you seen if Cython[0] would provide any benefit to your runtime performance?

      [0]: https://cython.readthedocs.io/en/latest/src/quickstart/cytho...

      • sieve 4 hours ago ago

        I looked at it briefly, but did not use it. I actually made an effort to use PyPy, but the issues I mentioned probably ensure that it will always lag behind CPython as far as language support is concerned.

        The situation is tricky and the friction is considerable. It is not like JS where v8 made the existing language blazing fast with no changes to the language itself.

        Would rather use something like Nim with Python-like syntax.

    • Drupon 3 hours ago ago

      >I joke that using Python on your modern 2020s CPU upgrades it to a Pentium 4 from 2004 running code compiled with C. And the 2004 version might still be faster.

      It really doesn't for a lot of the things that matter, and people should seriously ignore your opinions if you're making these kind of fatuous jokes. Any serious person should understand what CPU bound tasks are vs what IO bound ones are. Python is used for the latter, with some C/C++/Rust bindings for the former. You are ignorant and tedious. When should I actually give a fuck? is the question that you types that build nothing never manage to answer. If you can improve some significant metric by 50x by moving away from Python, you should be fired for having been stupid enough to choose the wrong tool for the job.

      • sieve 2 hours ago ago

        > Any serious person should understand what CPU bound tasks are vs what IO bound ones are.

        This is a decision fork only when you are stuck using a slow language. I don't have to do this --- at all --- when using C/Java and so many other languages.

        Using Python as glue and writing extensions in C/Rust is a choice. But I'd rather write everything in C23 by that point. Or move to a faster language if syntax/aesthetics is an issue.

        Further, you often do not have a choice on what platform you get to work with. Someone might have built an expensive-to-replace website using PHP. And then you have to build HipHop to speed it up.

  • undefined 9 hours ago ago
    [deleted]
  • actionfromafar 10 hours ago ago
  • luckydata 6 hours ago ago

    [flagged]