A discussion following this question left me wondering, so I decided to run a few tests and compare the creation time of set((x,y,z))
vs. {x,y,z}
for creating sets in Python (I'm using Python 3.7).
I compared the two methods using time
and timeit
.
Both were consistent* with the following results:
test1 = """
my_set1 = set((1, 2, 3))
"""
print(timeit(test1))
Result: 0.30240735499999993
test2 = """
my_set2 = {1,2,3}
"""
print(timeit(test2))
Result: 0.10771795900000003
So the second method was almost 3 times faster than the first.
This was quite a surprising difference to me.
What is happening under the hood to optimize the performance of the set literal over the set()
method in such a way? Which would be advisable for which cases?
* Note: I only show the results of the timeit
tests since they are averaged over many samples, and thus perhaps more reliable, but the results when testing with time
showed similar differences in both cases.
Edit: I'm aware of this similar question and though it answers certain aspects of my original question, it didn't cover all of it. Sets were not addressed in the question, and as empty sets do not have a literal syntax in python, I was curious how (if at all) set creation using a literal would differ from using the set()
method. Also, I wondered how the handling of the tuple parameter in set((x,y,z)
happens behind the scenes and what is its possible impact on runtime.
The great answer by coldspeed helped clear things up.
tuple(...)
. – Andras Deak[] vs list()
. The factors that make literal syntax faster are exactly the same. – Martijn Pieters♦set
literal", the one-eyed monkey operator:{*()}
. It uses unpacking generalizations with an emptytuple
(which is a singleton on CPython, so notuple
construction actually occurs) to impose the necessary context so Python sees aset
being constructed, rather than adict
. – ShadowRanger