Skip to content

gh-118218: Reuse return tuple in itertools.pairwise#118219

Merged
serhiy-storchaka merged 5 commits intopython:mainfrom
hauntsaninja:pairwise-faster
Apr 30, 2024
Merged

gh-118218: Reuse return tuple in itertools.pairwise#118219
serhiy-storchaka merged 5 commits intopython:mainfrom
hauntsaninja:pairwise-faster

Conversation

@hauntsaninja
Copy link
Contributor

@hauntsaninja hauntsaninja commented Apr 24, 2024

As per the comment, this is shamelessly based off of enumobject.c

With this change:

b1(1)            min=152.8us mean=155.5us ± 3.8us (25 repeats, 1000 loops)
b2(1)            min=149.0us mean=159.1us ± 8.8us (25 repeats, 1000 loops)
b3(1)            min=232.6us mean=242.5us ± 11.7us (25 repeats, 1000 loops)
b1(10)           min=279.2us mean=296.9us ± 16.6us (25 repeats, 1000 loops)
b2(10)           min=249.5us mean=259.2us ± 12.2us (25 repeats, 1000 loops)
b3(10)           min=386.6us mean=398.8us ± 10.1us (25 repeats, 1000 loops)
b1(1000)         min=20.3ms mean=20.7ms ± 0.5ms (25 repeats, 1000 loops)
b2(1000)         min=16.7ms mean=17.1ms ± 0.2ms (25 repeats, 1000 loops)
b3(1000)         min=26.0ms mean=26.2ms ± 0.3ms (25 repeats, 1000 loops)

Without this change:

b1(1)            min=142.2us mean=143.0us ± 0.9us (25 repeats, 1000 loops)
b2(1)            min=142.7us mean=143.3us ± 1.0us (25 repeats, 1000 loops)
b3(1)            min=219.8us mean=227.2us ± 4.4us (25 repeats, 1000 loops)
b1(10)           min=314.2us mean=323.8us ± 4.1us (25 repeats, 1000 loops)
b2(10)           min=335.4us mean=341.8us ± 5.1us (25 repeats, 1000 loops)
b3(10)           min=362.0us mean=386.2us ± 14.9us (25 repeats, 1000 loops)
b1(1000)         min=26.5ms mean=27.3ms ± 0.3ms (25 repeats, 1000 loops)
b2(1000)         min=29.8ms mean=30.2ms ± 0.2ms (25 repeats, 1000 loops)
b3(1000)         min=26.0ms mean=26.5ms ± 0.4ms (25 repeats, 1000 loops)

Benchmarking script:

Details
import statistics
import time
import timeit
from itertools import pairwise

def b1(n):
    for x in pairwise(range(n)):
        pass

def b2(n):
    for a, b in pairwise(range(n)):
        pass

def b3(n):
    list(pairwise(range(n)))


def format_time(t):
    if t >= 1e9:
        return f'{t/1e9:.1f}s'
    if t >= 1e6:
        return f'{t/1e6:.1f}ms'
    if t >= 1e3:
        return f'{t/1e3:.1f}us'
    return f'{t:.1f}ns'


def format_mean_stdev(ts):
    mean = statistics.mean(ts)
    stdev = statistics.stdev(ts)
    if mean >= 1e9:
        return f'{mean/1e9:.1f}s ± {stdev/1e9:.1f}s'
    if mean >= 1e6:
        return f'{mean/1e6:.1f}ms ± {stdev/1e6:.1f}ms'
    if mean >= 1e3:
        return f'{mean/1e3:.1f}us ± {stdev/1e3:.1f}us'
    return f'{mean:.1f}ns ± {stdev:.1f}ns'


def bench(stmt):
    repeat = 25
    number = 1000
    timings = timeit.repeat(
        stmt, globals=globals(), repeat=repeat, number=number, timer=time.perf_counter_ns
    )
    print(
        f'{stmt:16} '
        f'min={format_time(min(timings))} '
        f'mean={format_mean_stdev(timings)} '
        f'({repeat} repeats, {number} loops)'
    )

bench('b1(1)')
bench('b2(1)')
bench('b3(1)')

bench('b1(10)')
bench('b2(10)')
bench('b3(10)')

bench('b1(1000)')
bench('b2(1000)')
bench('b3(1000)')

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants