itertools.product slower than nested for loops

后端 未结 3 1013
再見小時候
再見小時候 2020-12-19 02:34

I am trying using the itertools.product function to make a segment of my code (in an isotopic pattern simulator) easier to read and hopefully faster as well (th

3条回答
  •  一生所求
    2020-12-19 03:08

    Your original itertool code spent a lot extra time in the needless lambda, and building lists of intermediate values by hand - a lot of this can be replaced with builtin functionality.

    Now, the inner for loop does add quite a lot extra overhead: just try the following and the performance is very much on par with your original code:

    for a in itertools.product(carbons,hydrogens,nitrogens,oxygens17,
                               oxygens18,sulfurs33,sulfurs34,sulfurs36):
        i, j, k, l, m, n, o, p = a
        totals.append((i[0]+j[0]+k[0]+l[0]+m[0]+n[0]+o[0]+p[0],
                       i[1]*j[1]*k[1]*l[1]*m[1]*n[1]*o[1]*p[1]))
    

    The following code runs as much as possible in the CPython builtin side, and I tested it to be equivalent to with code. Notably the code uses zip(*iterable) to unzip each of the product results; then uses the reduce with operator.mul for product, and sum for summing; 2 generators for going through the lists. The for loop still beats slightly, but being hardcoded it probably is not what you can use in the long run.

    import itertools
    from operator import mul
    from functools import partial
    
    prod = partial(reduce, mul)
    elems = carbons, hydrogens, nitrogens, oxygens17, oxygens18, sulfurs33, sulfurs34, sulfurs36
    p = itertools.product(*elems)
    
    totals = [
        ( sum(massdiffs), prod(chances) )
        for massdiffs, chances in
        ( zip(*i) for i in p )
    ]
    

提交回复
热议问题