2015-10-17 6 views
1

Так что я постоянно видел, как люди пишут код, когда они хотят видеть квадратную версию заданного значения, они будут выписывать x * x вместо x ** 2 , Существует ли такое большое перекрытие эффективности между этими двумя точками, что данная функция в python не просто используется, или это просто стилистическая точка? Я бы скорее использовал оператор **, но если это вызовет огромную ошибку, я должен делать операцию в миллиард раз, что я знаю, я бы хотел узнать. Также, если я ошибаюсь в порядке величины для операций, которые один берет на себя, я также хотел бы исправить это. т.е. если ** более эффективно, чем x * x, то я хотел бы знать, почему.* vs ** для мощности 2 операции

+1

Я думаю, что люди используют 'x * x' вместо' x ** 2', потому что он работает на всех языках, тогда как 'x ** 2' работает не в Java/C/C++. Поэтому я предполагаю, что причиной является незнание большинства примеров. Мне любопытно узнать, есть ли разница в эффективности/числовая разница. –

ответ

3

Я не согласен с g.d.d.c, умножение происходит намного быстрее!

"""Evaluating the difference in execution time between n*n and n**2""" 

from time import time 

n = 2 
t = time() 
for i in range(5000000): 
    n**2 
print("Time for n**2:\t%0.3f" % (time()-t)) 
t = time() 
for i in range(5000000): 
    n*n 
print("Time for n*n:\t%0.3f" % (time()-t)) 


def test(n): 
    """ 
    Difference in execution time between n*n and n**2 
    within function scope. 
    """ 
    t = time() 
    for i in range(5000000): 
     n**2 
    print("Time for n**2:\t%0.3f" % (time()-t)) 
    t = time() 
    for i in range(5000000): 
     n*n 
    print("Time for n*n:\t%0.3f" % (time()-t)) 

test(n) 

Результаты:

Time for n**2: 2.324496030807495 
Time for n*n: 0.5879969596862793 
Time for n**2: 2.0771241188049316 
Time for n*n: 0.2894318103790283 

Вы можете видеть, что умножение примерно в 4 раза быстрее, вне функции, и в 7 раз быстрее, в функции. Я не могу объяснить разницу между этими двумя тестами, и я не уверен в различии между n * n и n ** 2, но это может быть связано с тем, что Python является интерпретированным языком, а обработка последнего принимает больше времени, даже если операции процессора очень похожи, как демонстрирует gddc.

+1

Почему это имеет значение (и такое огромное!), Если оно находится в функции или вне функции? –

+1

@moose: Скорее всего, потому, что поиск глобальных переменных - это поиск по типу, в то время как локальный поиск переменных индексируется в массив. – user2357112

+1

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

2

Реально, два, вероятно, очень похожи на общую стоимость:

>>> def s1(x): 
... return x * x 
... 
>>> 
>>> def s2(x): 
... return x ** 2 
... 
>>> 
>>> from dis import dis 
>>> 
>>> dis(s1) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_FAST    0 (x) 
       6 BINARY_MULTIPLY 
       7 RETURN_VALUE 
>>> dis(s2) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    1 (2) 
       6 BINARY_POWER 
       7 RETURN_VALUE 
>>> 

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

И, для полноты картины, то timeit результаты:

>>> timeit.Timer("s1(10)", 'from __main__ import s1').timeit(100000) 
0.0186597650628606 
>>> timeit.Timer("s2(10)", 'from __main__ import s2').timeit(100000) 
0.018789616358585448 

, который появляется, чтобы показать, что x * x является очень немного быстрее в 100 000 итераций.

+0

Так что это сама по себе концепция стиля. Я всегда думал, что это просто что-то вроде функции pow() в c, поскольку он вызвал вызов функции, я увидел необходимость на этом языке, но на python, так как он встроен. Я просто не понимаю, почему использовать его. По моему мнению, это более выразительно, чем другое, до тех пор, пока оператор известен и понимается. Спасибо за этот фрагмент. –

+0

Для 10e6 это значение, но будет ли оно экспоненциально возрастать во времени или постоянно? Я знаю, что в грандиозной схеме это будет иметь значение чуть меньше, но с проблемами Project Euler, чтобы научить меня языку Python, а время, даже четверть секунды, немного возится со мной. –

+2

Nah. Экспоненциальность ** намного медленнее, чем умножение на обычные процессоры. Ваш тест не показывает это, потому что вовремя доминирует стоимость вызова функции (я предполагаю) или других динамических Phenon shenanigans. В скомпилированных языках разница является резкой. Даже в Python я мог представить, что это имеет большое значение в замкнутом цикле без вызова функции, но я не тестировал. Во всяком случае, это (к сожалению) далеко не досрочная оптимизация для многих приложений. –

Смежные вопросы