Set vs. frozenset performance

前端 未结 2 1702
时光取名叫无心
时光取名叫无心 2020-12-08 19:13

I was tinkering around with Python\'s set and frozenset collection types.

Initially, I assumed that frozenset would provide a

2条回答
  •  温柔的废话
    2020-12-08 19:31

    The frozenset and set implementations are largely shared; a set is simply a frozenset with mutating methods added, with the exact same hashtable implementation. See the Objects/setobject.c source file; the top-level PyFrozenSet_Type definition shares functions with the PySet_Type definition.

    There is no optimisation for a frozenset here, as there is no need to calculate the hashes for the items in the frozenset when you are testing for membership. The item that you use to test against the set still needs to have their hash calculated, in order to find the right slot in the set hashtable so you can do an equality test.

    As such, your timing results are probably off due to other processes running on your system; you measured wall-clock time, and did not disable Python garbage collection nor did you repeatedly test the same thing.

    Try to run your test using the timeit module, with one value from numbers and one not in the set:

    import random
    import sys
    import timeit
    
    numbers = [random.randrange(sys.maxsize) for _ in range(10000)]
    set_ = set(numbers)
    fset = frozenset(numbers)
    present = random.choice(numbers)
    notpresent = -1
    test = 'present in s; notpresent in s'
    
    settime = timeit.timeit(
        test,
        'from __main__ import set_ as s, present, notpresent')
    fsettime = timeit.timeit(
        test,
        'from __main__ import fset as s, present, notpresent')
    
    print('set      : {:.3f} seconds'.format(settime))
    print('frozenset: {:.3f} seconds'.format(fsettime))
    

    This repeats each test 1 million times and produces:

    set      : 0.050 seconds
    frozenset: 0.050 seconds
    

提交回复
热议问题