Время Python не работает? - PullRequest
3 голосов
/ 30 марта 2011

Может кто-нибудь объяснить мне, почему это происходит?

aatiis@aiur ~ $ time python /usr/lib64/python2.7/timeit.py -n 1 \
    -- 'x = 10**1000'
1 loops, best of 3: 0.954 usec per loop

real    0m0.055s
user    0m0.050s
sys     0m0.000s

aatiis@aiur ~ $ time python /usr/lib64/python2.7/timeit.py -n 1 \
    -- 'x = 10**100000'
1 loops, best of 3: 0.954 usec per loop

real    0m0.067s
user    0m0.040s
sys     0m0.020s

aatiis@aiur ~ $ time python /usr/lib64/python2.7/timeit.py -n 1 \
    -- 'x = 10**10000000'
1 loops, best of 3: 0.954 usec per loop

real    0m20.802s
user    0m20.540s
sys     0m0.170s

Я получаю точно такой же результат от timeit, но time говорит мне, что оценка 10**10000000 занимает больше 20 секунд. То же самое происходит, если я позвоню timeit от переводчика:

>>> t = time.time()
>>> print timeit.timeit('x = 10**10000000;', number=1)
5.00679016113e-06
>>> print time.time() - t
20.6168580055

Почему мой timeit не работает или что я делаю не так?

Дополнительная информация:

>>> print sys.version
2.7.1+ (2.7:4f07cacb2c3b+, Mar 28 2011, 23:11:59)
[GCC 4.4.5]

>>> print sys.version_info
>>> sys.version_info(major=2, minor=7, micro=2, releaselevel='alpha', serial=0)

UPDATE:

Вот еще одно очень интересное наблюдение:

>>> def run():
...     t = time.time()
...     x = 10**10000000
...     print time.time() - t

Когда я нажимаю клавишу ввода после определения этой функции, потребуется около полминуты, пока я не вернусь к приглашению. А потом:

>>> run()
2.14576721191e-06

Почему это происходит? Тело функции предварительно компилируется или оптимизируется каким-либо образом?

Ответы [ 2 ]

5 голосов
/ 30 марта 2011

Полагаю, проблема в том, как вы заявляете о проблеме на timeit.Я думаю, что происходит то, что выражение вычисляется один раз, когда тестовое выражение компилируется, а затем просто просматривается (а не переоценивается) с каждым циклом timeit.Таким образом, в настоящее время все, что вы измеряете, это время, которое требуется для выполнения задания, а не для расчета.

Вам нужно будет принудительно выполнять вычисления каждый раз:

timeit.timeit('x = 10; y = 100; z = x ** y')

Редактировать: в ответ на ваш следующий вопрос тело функции оптимизируется.Компилятор видит 10*100000 и понимает, что он никогда не изменится, поэтому вычисляет его во время компиляции, а не во время выполнения.

4 голосов
/ 31 марта 2011

Сравнить:

>>> import dis
>>> def run():
...     return 10**100
... 
>>> dis.dis(run)
  3           0 LOAD_CONST               3 (100000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000L)
              3 RETURN_VALUE        

И

>>> def runvar():
...     x = 10
...     return x**100
... 
>>> dis.dis(runvar)
  3           0 LOAD_CONST               1 (10)
              3 STORE_FAST               0 (x)

  4           6 LOAD_FAST                0 (x)
              9 LOAD_CONST               2 (100)
             12 BINARY_POWER        
             13 RETURN_VALUE        

Обратите внимание, что BINARY_POWER выполняется во время выполнения только во втором случае. Так что timeit ведет себя как следует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...