Python has some unusual performance behaviors. IIRC you can also speed up the performance of your program a lot by assigning intermediate variables instead of referencing properties, for example: [A.b[i] for i in range(100)] is a lot slower than: B = A.b [B[i] for i in range (100)]
Incrementally improving the performance of a Python script
21–24 of 24 posts
Re: Incrementally improving the performance of a Python script
#22Allocating registers for all local vars statically means scopes have different sizes, which in turn complicates slab allocation and/or reuse. In return for being easier to reason about (except for the main scope issue) and saving space.
I opted for a fixed number of linearly assigned registers per scope in Snigl [0]; once the limit is reached, remaining variables are stored in a table. Which means I sort of get both, since additional scopes may be added using {} (it could make sense to add a scope: keyword to Python) if that becomes an issue.
It's all compromises, all the way down.
Re: Incrementally improving the performance of a Python script
#23Python has some unusual performance behaviors. IIRC you can also speed up the performance of your program a lot by assigning intermediate variables instead of referencing properties, for example: [A.b[i] for i in range(100)] is a lot slower than: B = A.b [B[i] for i in range (100)]
I'm not sure about other implementations, but "optimizing" CPython ends up being optimizing against counter-intuitive interpreter internals rather than time-complexity of the code. For example, in CPython 3.6, n = 0 d = 100 for i in range(10**6): n += i if n >= d: n %= d is slower than n = (n + i) % d This counter to lower level languages, where dividing by a variable is costly, and the CPU can predict the pipeline t…
I think there's a bug in the code then. It will be skipped a few times, but for i between 100 and 10^6, the condition is guaranteed true every time.