Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is `{*l}` faster than `set(l)` - python sets (not really only for sets, for all sequences)

So here is my timings:

>>> import timeit
>>> timeit.timeit(lambda: set(l))
0.7210583936611334
>>> timeit.timeit(lambda: {*l})
0.5386332845236943

Why is that, my opinion would be equal but it's not.

So unpacking is fast from this example, right?

like image 719
U12-Forward Avatar asked Oct 25 '25 06:10

U12-Forward


1 Answers

For the same reason [] is faster than list(); the interpreter includes dedicated support for syntax based operations that uses specialized code paths, while constructor calls involve:

  1. Loading the constructor from built-in scope (requires a pair of dict lookups, one in global scope, then another in built-in scope when it fails)
  2. Requires dispatch through generic callable dispatch mechanisms, and generic argument parsing code, all of which is far more expensive than a single byte code that reads all of its arguments off the stack as a C array

All of these advantages relate to fixed overhead; the big-O of both approaches are the same, so {*range(10000)} won't be noticeably/reliably faster than set(range(10000)), because the actual construction work vastly outweighs the overhead of loading and calling the constructor via generic dispatch.

like image 85
ShadowRanger Avatar answered Oct 26 '25 20:10

ShadowRanger