Почему побитовые операторы медленнее, чем умножение / деление / по модулю? - PullRequest
0 голосов
/ 05 января 2019

Хорошо известен тот факт, что умножение, целочисленное деление и модуль по степеням двух можно более эффективно переписать как побитовые операции:

>>> x = randint(50000, 100000)
>>> x << 2 == x * 4
True
>>> x >> 2 == x // 4
True
>>> x & 3 == x % 4
True

В скомпилированных языках, таких как C / C ++ и Java, тесты показали, что побитовые операции обычно быстрее, чем арифметические операции. (См. здесь и здесь ). Однако, когда я тестирую их в Python, я получаю противоположные результаты:

In [1]: from random import randint
   ...: nums = [randint(0, 1000000) for _ in range(100000)]

In [2]: %timeit [i * 8 for i in nums]
7.73 ms ± 397 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [3]: %timeit [i << 3 for i in nums]
8.22 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [4]: %timeit [i // 8 for i in nums]
7.05 ms ± 393 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [5]: %timeit [i >> 3 for i in nums]
7.55 ms ± 367 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [6]: %timeit [i % 8 for i in nums]
5.96 ms ± 503 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [7]: %timeit [i & 7 for i in nums]
8.29 ms ± 816 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Как видите, побитовые операции выполняются медленнее, чем их арифметические аналоги, особенно по модулю. Я повторил этот тест для другого набора чисел, и получил тот же результат. Для этого есть причина? Эти тесты были в CPython 3.6.7, если это имеет значение.

Ответы [ 2 ]

0 голосов
/ 05 января 2019

*, % и / имеют быстрые пути для целых чисел с одной конечностью. <<, >> и & нет. Они проходят путь кода общего назначения с произвольной точностью.

0 голосов
/ 05 января 2019

Python - интерпретируемый язык, поэтому вы можете потерять скорость в любом месте из-за сложной массы инструкций, отделяющих вас от машинного кода.

Если такая разница в скорости имеет для вас значение, вам, вероятно, следует использовать NumPy, что позволит вам выполнять массовую обработку чисел на уровне, намного более близком к скомпилированному коду.

...