16 ms·
Why Python is Slow: Looking Under the Hood (2014)
- anon1253 9y agoExcept it isn't really. Yes, Python is incredibly slow for day to day stuff, but the sheer amount of easy to use numerical libraries (numpy, scipy, scikit-learn, tensorflow, keras, opencv, just to name a few) make it one of the fastest out there for numerical computation. I tried doing some numerical heavy stuff on the JVM (with Java and Clojure) and it fights you every step of the way ... and that has static typing and all the things the article mentions. Of course, Python derives that functionality from C and Fortran … but just having that interop at your fingertips is magical in terms of productivity. I still get nightmares from working with the JNI.
- pjmlp 9y agoThe point is not having to write C and Fortran in first place.
- dr_zoidberg 9y agoAs a heavy user of numpy, I use a lot of C and Fortran code, without having to write it.
- deleted 9y ago[deleted]
- jeremyjh 9y agoThis point is addressed in literally the first paragraph of the submitted article.
- plasticxme 9y agoIf you read the post, you’d know that you’ve basically summarized it.
- dnautics 9y agoJulia is all three, yet it's fast (allowing for jit, which in Julia is a one time cost). It's worth noting that those properties themselves are not what's critical, so much as designing around it and allowing for fast paths through critical code (locking down the dynamic types, first class array datatypes with packed forms)...
- azag0 9y agoIt's rather the degree to which Python is dynamic that makes it slow. PyPy could be considered an implicit JIT compiler for Python, yet it is still far slower than Julia. The level of magic you can apply to Python objects that the interpreter/compiler must support is just a different league than Julia. I'd be interested if someone could compare to JS.
- pjmlp 9y agoLisp, Smalltalk, Dylan and SELF allow for the same kind of magic. The JIT developed for SELF is the genesis of Hotspot. JRuby guys have a quite good implementation making use of Graal, and Ruby is not less magical than Python. In the end it boils down to how much the community prefers to keep on using C, or improve PyPy. EDIT: Fixed auto-correction induced typo.
- shellac 9y agos/Gradle/Graal/? In the case of python it's clear that the heavy reliance on c extensions is a blessing and a curse: it's kept python relevant in communities like science even though it isn't very fast. However one of the lessons of Graal seems to be that such extensions can seriously prohibit improving performance, since they are opaque to JITs. There's a few talks by Chris Seaton (e.g. https://www.youtube.com/watch?v=YLtjkP9bD_U https://www.youtube.com/watch?v=YLtjkP9bD_U) on the topic.
- pjmlp 9y agoYeah, typo due to auto-correction.
- chmaynard 9y agoFrom the article: "Dynamic typing makes Python easier to use than C." The author gives no justification for this claim. Do any language experts care to comment?
- winter_blue 9y agoI'm a big fan of strong static type systems. I believe type-safety increases code quality significantly. I used to think several years ago, that the main benefit of strong static typing was code safety / eliminating a whole class of bugs. But I've changed my opinion. I now think the biggest benefit is that it makes the code a lot easier for other people to read and understand. I mean I have multiple personal projects where I've used Python (which is a dynamically typed language), but these are small one-off projects. But I think when working in a team, especially a large team, having types becomes a huge thing. Having types for objects is especially useful. Having types forces you to think more clearly about the structure of your data. It's really sad when I see `foo(bar)`, and I have no idea what the type of `bar` is, and if it's an object, I have no idea what fields `bar` has. I have to simply guess the structure of the various implicit types by looking at the code (sigh). It makes the code difficult to read, and rather unpleasant to work on. Not to mention, all the multitude of bugs that come from duck/dynamic typing. I don't think good statically typed languages are hard to use at all. Type inference has spread everywhere that the old argument of having to repeat your types doesn't hold anymore. TypeScript, Flow (JavaScrpt), Haskell, languages from the ML family are really good at type inference. Even the `auto` type inference in C++17 was better than I'd expected.
- icebraining 9y agoTechnically Python is now an optionally-typed language, as of version 3.5. It won't actually check the types out-of-the-box, but it has support for annotating variables and functions with their types. A separate project (mypy) can then read and check those types, and it does some inference too. You can see typed examples here: http://mypy-lang.org/examples.html http://mypy-lang.org/examples.html
- 9y ago
- lispm 9y ago> Python being a dynamically typed, interpreted language 'CPython' is the defining implementation of the dynamically typed language 'Python' using a byte-code VM (and no jit compiler). bash-3.2$ time /tmp/bench.py 5000000050000000 real 0m19.763s user 0m15.015s sys 0m4.309s 'SBCL' is an implementation of the dynamically typed language 'Common Lisp' using a native code compiler. bash-3.2$ time /tmp/bench.lisp 5000000050000000 real 0m0.319s user 0m0.294s sys 0m0.017s The unoptimized code is roughly 65 times faster in SBCL compared to CPython - including startup time.
- exikyut 9y agoThis is an unreproducible benchmark. Can we have the programs you used?
- lispm 9y agoSee the comments in the original article for the python examples... The Lisp program is basically this: (format t "~a~%" (loop for i from 1 upto 100000000 sum i)) The Python code can be made a lot faster by using xrange and also reduce. But then the SBCL compiler can optimize a type declared version down to 0.07 seconds runtime for the script. (locally (declare (optimize (speed 3) (debug 0) (safety 0))) (format t "~a~%" (loop for i fixnum from 1 upto 100000000 sum i of-type fixnum)))
- acdha 9y ago> The Python code can be made a lot faster by using xrange and also reduce. This is a key distinction since it reveals that most of the difference is due to these programs doing different things. Changing this to compare the same thing shows why this matters: cadams@jupiter:~ $ sbcl --version SBCL 1.4.0 cadams@jupiter:~ $ python2.7 --version Python 2.7.14 cadams@jupiter:~ $ pypy --version Python 2.7.13 (84a2f3e6a7f88f2fe698e473998755b3bd1a12e2, Oct 05 2017, 16:34:13) [PyPy 5.9.0 with GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] cadams@jupiter:~ $ time ./test.lisp 5000000050000000 real 0m0.209s user 0m0.194s sys 0m0.011s cadams@jupiter:~ $ time python2.7 test.py 5000000050000000 real 0m0.758s user 0m0.744s sys 0m0.008s cadams@jupiter:~ $ time pypy test.py 5000000050000000 real 0m0.123s user 0m0.101s sys 0m0.019s So at the end of that we've discovered two things we already knew: an interpreter is slower than a JIT given enough work to balance the startup time, and that allocating a list with millions of items and then immediately discarding it is more expensive than summing an iterator. Since Python 3 made range() lazy by default, the core developers clearly agree that this is better than allocating lists unless explicitly requested.
- hasenj 9y agoPython is optimized for small programs being easy and quick (and pleasant) to write. Every other use case it fails in some way. For being slow. For lacking static typing. For lacking compilation. For having a GIL. etc.
- anewhnaccount2 9y agoThis is too categorical. And also it fails to define when small stops being small (and so is easy to defend by moving the goalposts). Yes, these are real problems, but some of them have (partial) solutions. You can use one of the many solutions to write a C, C++, cython and so on extension. You can have type checking with mypy. You can produce executable with cx_freeze (not compilation, but compilation is more of a solution than a problem). You can create parallel programs using multiprocessing. (etc.)
- weberc2 9y agoWriting extensions in c/c++ largely negates all stated benefits of using Python in the first place, and I'm proficient in all three languages. Further, mypy is hopeful, but it's not quite there yet (lots of holes and bugs--notably no support for recursive types). Lastly multiprocessing for parallelism is a poor man's solution, and far from what I've become accustomed to in Go, Rust, etc. Python is a nice language and it pays my bills, but Go beats it at many of its own purported strengths, in my opinion.
- hasenj 9y agoUsing these solution makes the development process much more troublesome than it needs to be, thus defeating the whole point of using python.
- ptero 9y agoHowever, as posters in other thread said, the number and availability of libraries makes functionality of those small programs exceed that of much larger ones written in C or a similar language. If you have to write a large project from scratch in Python it will be slow, but Python has gone pretty far in the direction where for many large tasks 90% of the functionality will be obtainable through standard libraries. Doing the remaining 10% in basic Python often keeps it competitive at runtime with compiled languages but produce much simpler, shorter and easier to maintain code.
- jokoon 9y agoHow compatible are existing python libraries with pypy, and is the official python taking clues from pypy? Is there more work to do to make pypy even faster?
- dr_zoidberg 9y agoSome complex libraries needed special porting (eg. NumPyPy), and there was work under way to get rid of that and provide a CPython compatible interface. The CPython team does take clues from PyPy (eg: see the CPy3.6 dict implementation), but they are also a lot more careful (some might say "slower") to adopt changes. Both teams also seem to have some ideological differences on how to face the long term development of the language (usualy, GvR goes for "simpler" instead of "more performant").
- wyldfire 9y agoEverything I've ever tried with pypy Just Worked. Python packages w/C-extensions have been harder to get right in the past but now PyPy does some excellent C-API emulation.
- baybal2 9y agoA thing much bigger than GIL for Python is that in python bytecode, objects are used as primitives.
- wruza 9y ago>[boxed values...] The dynamic typing means that there are a lot more steps involved with any operation. This is a primary reason that Python is slow compared to C for operations on numerical data. Not exactly. Setting typecodes and vals doesn’t slow things down by many orders of magnitude. The main reason python is relatively slow is that there is no practical way to reason about what parts of program may be optimized out or leveled down to native datatypes and then restructured in a very efficient way. This is what optimizing/jit compilers do to achieve much performance; this one is the source of x100, not unboxing on its own. Technically, tracing jit that doesn’t care if you’re writing in static or dynamic, strict or duck typing can be done for any language, but (afaik) python is not very jit-friendly in general.
- ryanplant-au 9y agoDoes JavaScript make it easier to reason about those potentially-optimizable areas? Which language features make it easier to optimize to the level that V8 is? (V8 being 7-10x faster than CPython 3 on most of the Benchmarks Game.)
- lorenzfx 9y agoI believe this article [0] (previous discussion [1]) from one of pyston's authors gives a much better overview of why python is slow. [0] http://blog.kevmod.com/2016/07/why-is-python-slow/ http://blog.kevmod.com/2016/07/why-is-python-slow/ [1] https://news.ycombinator.com/item?id=12025309 https://news.ycombinator.com/item?id=12025309
- mikebenfield 9y agoAlthough I use and enjoy Python for some purposes, I can't help by see all the effort gone into improving Python performance (including Pypy, Cython, rewriting code in C, etc) as fixing a self-inflicted wound. Why are we using a language whose semantics make it very difficult to execute quickly?
- wyldfire 9y agoBecause virtually nothing is bound to anything until we get to this line of code, Python is the ultimate dynamic language. I find that the vast majority of Python code that I write is not processor-bound or memory-bound. It's disk or network bound (and still would be if I wrote it in C). It's also much simpler to teach programming in than alternatives.
- Kpourdeilami 9y agoThe tooling and ecosystem around it are pretty much unrivalled
- cjbillington 9y agoWell, if you rewrite in C, you're not using the language whose semantics make it difficult to execute quickly - you're using C. One of the great things about Python is the (relative) ease of interfacing with code written in another language (particularly C), so I don't see this as a square-peg-round-hole situation. You're using the right tool for the job, possibly on the per-function level instead of per-project, but it's much the same. I really don't see the speed thing as a problem. I write everything in Python until it's slow, then I write some Cython or cuda for the bottleneck. No biggie. One language doesn't need to do everything, and with the particular set of compromises it has made, Python seems to cover a wider range of general-purposesness than most languages, so I'm happy.
- adenadel 9y agoI thought this was pretty neat # WARNNG: never do this! id113 = id(113) iptr = IntStruct.from_address(id113) iptr.ob_digit = 4 # now Python's 113 contains a 4! 113 == 4 And now since the proper value 113 doesn't exist you have to resort to the binary representation on your system to revert back to normal behavior ctypes.cast(id113, ctypes.POINTER(ctypes.c_char))[3 * 8] = b'\x71'
- tjpnz 9y agoAnd yet there are entire industries built on the back of it. Everytime you see a a movie there'll be some Python code somehow responsible for the pixels you're seeing on the big screen.
- criley2 9y agoThis is perhaps a great example of why "speed" is a poorly descriptive term for software. In automobiles, we wouldn't call a large truck "fast" even though it has a much larger (and more "performant") engine than a small car. That small car is likely "much faster" than the truck, and yet cannot do most of the things the truck does. Sure, python is popular and important, but I don't think that popularity and "speed" are necessarily all that connected at all, except in use-cases where speed is the most important factor (say, financial transactions). When overnight rendering 3d graphics, speed is important but final product and ease of use are probably more important, since you can compensate for speed with a larger render farm. But more bank server aren't necessarily going to reduce transaction latency (in fact could increase it) so the gains there must often be at a much lower level.
- nayuki 9y agoI agree with this article. In practice, when writing number-crunching code in Python versus Java, I found that Python is usually 10 to 30× slower than Java, sometimes even 100× slower. See: https://www.nayuki.io/page/project-euler-solutions#benchmark-timings https://www.nayuki.io/page/project-euler-solutions#benchmark...
- ryanpcmcquen 9y agoCounter? https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13...