4 ms·
One of the biggest contributors in Python's (lack of) speed is dynamic typing. While a jump is a jump and an assignment is an assignment, an addition is more li
by AlexTWithBeard 4y ago
One of the biggest contributors in Python's (lack of) speed is dynamic typing. While a jump is a jump and an assignment is an assignment, an addition is more like "hmm... what is a left operand... is it double? what is a right operand? wow, it's also a double! okay, cpu add eax, ebx".
- deleted 4y ago[deleted]
- gpderetta 4y agoThere are a lot of dynamically typed languages that are significantly faster than python. Late binding issues can be effectively worked around.
- AlexTWithBeard 4y agoDo you have an example of a dynamically typed language where, say, addition of two lists of doubles would be significantly faster than in Python?
- bobbylarrybobby 4y agoDoesn't that sort of operation become very fast in JS after a few runs?
- fmakunbound 4y agoProbably most Common Lisp implementations.
- gpderetta 4y agoYou mean concatenating the lists or pairwise addition? I don't expect the former to be slow in python as it would be a primitive implemented in C (although even a simple lisp interpreter can have an advantage here by just concatenating the conses). For the latter, any language runtime capable of inference should be able to optimize it.
- skruger 4y agoRacket
- deleted 4y ago[deleted]
- samatman 4y agoI would expect this microbenchpark in particular to be as fast in LuaJIT as it would be in C, without the risk of undefined behavior if the array boundaries are improperly calculated.
- Sesse__ 4y agoLuaJIT.
- Qem 4y agoAssuming you mean pairwise addition, Pharo achieves over twice Python speed, in my laptop. Python version: from random import randrange from time import time def main(): L = [float(randrange(2**52, 2**53)) for _ in range(20000000)] M = [float(randrange(2**52, 2**53)) for _ in range(20000000)] t0 = time() N = [ x+y for x,y in zip(L, M) ] print('Concluded in', round(1000*(time() - t0)), 'millisec.') main() Results: Python 3.10.5 (main, Jun 9 2022, 00:00:00) [GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux Type "help", "copyright", "credits" or "license()" for more information. ============ RESTART: /run/media/user/KINGSTON/benchmark_doubles.py ============ Concluded in 1904 millisec. Pharo 10 version: | L M N t0 | Transcript clear. L := (1 to: 2e7) collect: [ :each | (( 2 raisedTo: 52 ) to: ( 2 raisedTo: 53 )) atRandom asFloat ]. M := (1 to: 2e7) collect: [ :each | (( 2 raisedTo: 52 ) to: ( 2 raisedTo: 53 )) atRandom asFloat ]. t0 := DateAndTime now. M := L with: M collect: [ :x :y | x + y ]. Transcript show: 'Concluded in ' , ((DateAndTime now - t0) asMilliSeconds asInteger ) asFloat asString , ' millisec.'; cr. Results: Concluded in 914.0 millisec.
- staticassertion 4y agoAlso "what is equals?". That's why people will do: def fooer(i: str, strings: list[str]): push = str.append for s in strings: push(i, s) Apparently this helps the interpreter understand that `append` is not getting overwritten in the global scope elsewhere.
- wheelerof4te 4y agoThis is one of the most common optimizations in Python, simply because the lookup code for modules/class instances is horrible and slow.
- staticassertion 4y agoIt'd be nice if there were a tool you could run over your code that did this sort of thing. Even if it can technically break shit in absurd cases, I'd totally run it on my code, which isn't absurd.
- Sesse__ 4y agoIf it's double, it probably would be addss xmm0, xmm1 :-) (add eax, ebx would be for 32-bit integers.)