Подтвердить что ты не робот

Является & быстрее% при проверке нечетных чисел?

Чтобы проверить нечетное и четное целое число, самая низкая битная проверка более эффективна, чем использование modulo?

>>> def isodd(num):
        return num & 1 and True or False

>>> isodd(10)
False
>>> isodd(9)
True
4b9b3361

Ответ 1

Угу. Модуль timeit в стандартной библиотеке - это то, как вы проверяете эти вещи. Например:

AmAir:stko aleax$ python -mtimeit -s'def isodd(x): x & 1' 'isodd(9)'
1000000 loops, best of 3: 0.446 usec per loop
AmAir:stko aleax$ python -mtimeit -s'def isodd(x): x & 1' 'isodd(10)'
1000000 loops, best of 3: 0.443 usec per loop
AmAir:stko aleax$ python -mtimeit -s'def isodd(x): x % 2' 'isodd(10)'
1000000 loops, best of 3: 0.453 usec per loop
AmAir:stko aleax$ python -mtimeit -s'def isodd(x): x % 2' 'isodd(9)'
1000000 loops, best of 3: 0.461 usec per loop

Как вы видите, на моем (первый день == old == slow;-) Macbook Air решение & повторяется между 7 и 18 наносекундами быстрее, чем решение %.

timeit не только скажет вам, что быстрее, но и сколько (просто запускайте тесты несколько раз), что обычно показывает, насколько это крайне важно (вам действительно интересно разницу в 10 наносекунд, когда накладные расходы вызов функции составляет около 400?! -)...

Убедительные программисты, которые, по сути дела, не оптимизируют микро-оптимизации, оказались невыполнимой задачей - хотя это было 35 лет (по сравнению с тем, что компьютеры получили порядок быстрее!), так как Knuth писал

Мы должны забыть о небольших эффективности, скажем, около 97% время: преждевременная оптимизация - это корень всего зла.

который, как он объяснил, является цитатой из еще более старого заявления Хора. Я думаю, что все полностью убеждены, что ИХ дело падает на оставшиеся 3%!

Поэтому вместо бесконечного повторения "это не имеет значения", мы (Тим Петерс, в частности, заслуживает там почестей) помещали в стандартный библиотечный модуль Python timeit, что делает его тривиально простым для измерения таких микро-тестов и тем самым, по крайней мере, некоторые программисты убеждают себя в том, что, хм, этот случай попадает в группу 97%! -)

Ответ 2

Чтобы быть абсолютно честным, Я не думаю, что это важно.

Первая проблема - читаемость. Что имеет смысл для других разработчиков? Я лично ожидал бы модулю при проверке четности/нечетности числа. Я ожидал бы, что большинство других разработчиков ожидали бы того же самого. Введя другой и неожиданный метод, вы можете сделать чтение кода и, следовательно, техническое обслуживание, более сложным.

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

Ответ 3

Лучшая оптимизация, которую вы можете получить, - не подвергать тест функции. "number % 2" и "число и 1" - очень распространенные способы проверки четности/четности, опытные программисты сразу узнают шаблон, и вы всегда можете добавить комментарий, например "#, если число нечетное, тогда бла-бла-бла" если вам действительно нужно, чтобы это было очевидно.

# state whether number is odd or even
if number & 1:
    print "Your number is odd"
else:
    print "Your number is even"

Ответ 4

"return num и 1 и True или False"? Вах! Если вы быстро сумасшедший (1) "return num и 1" (2) inline, он: if somenumber % 2 == 1 является разборчивым и битным isodd(somenumber), потому что он избегает вызова функции Python.

Ответ 5

Джон поднимает хороший момент. Реальные служебные данные находятся в вызове функции:
[email protected] ~> python -mtimeit -s'9 % 2'
10000000 loops, best of 3: 0.0271 usec per loop
[email protected] ~> python -mtimeit -s'10 % 2'
10000000 loops, best of 3: 0.0271 usec per loop

[email protected] ~> python -mtimeit -s'9 & 1'
10000000 loops, best of 3: 0.0271 usec per loop
[email protected] ~> python -mtimeit -s'9 & 1'
10000000 loops, best of 3: 0.0271 usec per loop

[email protected] ~> python -mtimeit -s'def isodd(x): x % 2' 'isodd(10)'
1000000 loops, best of 3: 0.334 usec per loop
[email protected] ~> python -mtimeit -s'def isodd(x): x % 2' 'isodd(9)'
1000000 loops, best of 3: 0.358 usec per loop

[email protected] ~> python -mtimeit -s'def isodd(x): x & 1' 'isodd(10)'
1000000 loops, best of 3: 0.317 usec per loop
[email protected] ~> python -mtimeit -s'def isodd(x): x & 1' 'isodd(9)'
1000000 loops, best of 3: 0.319 usec per loop

Интересно, что оба метода запоминают одно и то же время без вызова функции.

Ответ 6

Помимо оптимизации зла, он убирает очень идиоматический "var% 2 == 0", который понимает каждый кодер, не глядя дважды. Таким образом, это нарушает питон zen, а также очень мало.

Кроме того, a = b и True или False были заменены для лучшей удобочитаемости с помощью

return True, если num и 1 else False

Ответ 7

Был действительно удивлен, что ни один из вышеперечисленных ответов не установил обе переменные настройки (временный литерал - это разная история) и никакой вызов функции (который явно скрывает "нижние термины" ). Застрял на этом тайм-ауте от ipython timeit, где я получил явный победитель x & 1 - лучше на ~ 18%, используя python2.6 (~ 12%, используя python3.1).

На моей очень старой машине:

$ python -mtimeit -s 'x = 777' 'x&1'
10000000 loops, best of 3: 0.18 usec per loop
$ python -mtimeit -s 'x = 777' 'x%2'
1000000 loops, best of 3: 0.219 usec per loop

$ python3 -mtimeit -s 'x = 777' 'x&1'
1000000 loops, best of 3: 0.282 usec per loop
$ python3 -mtimeit -s 'x = 777' 'x%2'
1000000 loops, best of 3: 0.323 usec per loop