[Python] Performance of list.extend slice vs islice

Discussão em 'Python' iniciado por Stack, Maio 2, 2025.

  1. Stack

    Stack Membro Participativo

    It seems that even when islice would theoretically be better, in practice it is slower than just using slice. So I am a bit puzzled by the difference in performance between the usage of slice and islice here:

    from time import perf_counter
    from itertools import islice
    from random import choices
    from string import ascii_letters
    import sys

    test_str = "".join(choices(ascii_letters, k=10 ** 7))

    arr1 = []
    t0 = perf_counter()
    for _ in range(10):
    arr1.extend(test_str[slice(1, sys.maxsize)])
    t1 = perf_counter()
    print('%5.1f ms ' % ((t1 - t0) * 1e3))

    arr2 = []
    t0 = perf_counter()
    for _ in range(10):
    arr2.extend(islice(test_str, 1, sys.maxsize))
    t1 = perf_counter()
    print('%5.1f ms ' % ((t1 - t0) * 1e3))


    552.6 ms
    786.0 ms


    To justify why I believe the difference to be unexpected, here is my mental model for how the execution goes for both cases:

    Strict Slicing:

    • Allocate tmp, where tmp is the immutable string from 1th index to end on the original string.
    • Acquire an iterator over tmp.
    • Create string objects for each individual character.
    • Pass those string objects to be appended to the list.
    • Garbage collect tmp.

    Lazy Slicing:

    • Acquire an iterator over test_str, discarding the first value.
    • Create string objects for each individual character.
    • Pass those string objects to be appended to the list.

    I don't see how allocating the whole string object at once just to be garbage collected later leads to still better performance, specially considering the fact that both slicing methods are implemented in C.

    Continue reading...

Compartilhe esta Página