Почему разница в производительности между `|` и `или` различна для разных значений? - PullRequest
0 голосов
/ 24 октября 2019

Я рассчитывал производительность для операторов, я нашел это:

>>> timeit.timeit("10000000<2 or 10000000>1000",number=10000000)
0.4213107880004827
>>> timeit.timeit("10000000<2 | 10000000>1000",number=10000000)
0.4490717669996229

>>> timeit.timeit("1000<200000 or 100>1000",number=10000000)
Out[152]: 0.26014828799998213
>>> timeit.timeit("1000<200000 | 100>1000",number=10000000)
Out[151]: 0.4478519629992661

Хотя разница иногда незначительна, or постоянно бьет | для этих сравнений большого числа (я не совсем уверен, еслиэто из-за больших чисел или нет).

Но тогда:

>>> timeit.timeit("0 or 1",number=10000000)
Out[134]: 0.17863203100023384
>>> timeit.timeit("0 | 1",number=10000000)
Out[135]: 0.06668136799999047

>>> timeit.timeit("00000 | 111111",number=10000000)
Out[136]: 0.06739834499967401
>>> timeit.timeit("00000 or 111111",number=10000000)
Out[137]: 0.1818816989998595

>>> timeit.timeit("True or False",number=10000000)
Out[138]: 0.12497510200046236
>>> timeit.timeit("True | False",number=10000000)
Out[139]: 0.06938139100020635

>>> timeit.timeit("False | True",number=10000000)
Out[140]: 0.0667262490005669
>>> timeit.timeit("False or True",number=10000000)
Out[141]: 0.1443343150003784

Что происходит? Это ожидается? Я считал, что | всегда проверяет оба операнда, даже если первый оценивается как True. Так, по крайней мере, для случаев, когда 1-й операнд равен True, разве or не должен быть последовательно быстрее? Конечно, такой вопрос уже задавался в SO, но я не смог его найти, я буду рад, если кто-то укажет мне на это. Спасибо!

1 Ответ

0 голосов
/ 24 октября 2019

или и |это совсем не одинаковые операторы.

or выполняет логическое сокращение или тогда, когда | выполняет битовый код или

result = expression1 or expression2 

идентично

if bool(expression1):
    result = expression1
else:
    result = expression2

поэтому выражение2 даже не вычисляется, если выражение1 истинно

, тогда как:

result = expression1 |Выражение2

выполняет немного или оба значения. поэтому expression1 и expression2 должны давать целые числа. (Истина интерпретируется как целое число 1)

посмотрите, например, на следующий вывод

In [8]: "{0:b}".format(0b100 | 0b001)                                           
Out[8]: '101'

In [9]: "{0:b}".format(0b100 or 0b001)                                          
Out[9]: '100'

Так что я согласен с вашим предположением, что обычно or должно быть быстрее, чем |, ночтобы быть на 100% уверенным, что вам пришлось смотреть на байт-код.

Я ожидаю, что ваше предположение будет верным, если вы будете время от времени повторять операции. скажем, время их несколько сотен раз в разное время дня. для обоих.

Проблема с timeit состоит в том, что вы запускаете python в ОС, которая запускает несколько процессов и где у вас нет 100% предсказуемой среды.

Так что я будуочень осторожно интерпретировать крошечные различия во времени выполнения.

...