我想测试两个相同列表之间的处理时间,特别是正常列表和numpy列表.我的代码是
import timeit
import numpy as np
t = timeit.Timer("range(1000)")
print t.timeit()
u = timeit.Timer("np.arange(1000)")
print u.timeit()
Run Code Online (Sandbox Code Playgroud)
计算t很好,但对于uNameError:未列出全局名称'np'.
我应该如何编码以获得处理时间?
我没有看到为什么python的timeit模块使用the来测量时间的原因best of 3.这是我的控制台的一个例子:
~ python -m timeit 'sum(range(10000))'
10000 loops, best of 3: 119 usec per loop
Run Code Online (Sandbox Code Playgroud)
直觉上,我会将整个时间放在一起然后除以循环次数.在所有循环中获得最佳3的直觉是什么?这似乎有点不公平.
我总是使用Python的timeit库为我的小Python程序计时.现在我正在开发一个Django应用程序,我想知道如何计算我的Django函数,尤其是查询.
例如,我def index(request)在views.py中有一个在加载索引页面时会执行一些操作.如何timeit在不改变现有功能的情况下使用此特定功能的时间?
假设我有一些函数接受一个数组并将每个元素更改为0.
def function(array):
for i in range(0,len(array)):
array[i] = 0
return array
Run Code Online (Sandbox Code Playgroud)
我想测试这个函数在随机数组上运行需要多长时间,我希望生成timeit测试的OUTSIDE.换句话说,我不希望将生成数组所花费的时间包括在内.
我首先在变量x中存储一个随机数组并执行:
timeit.timeit("function(x)",setup="from __main__ import function")
Run Code Online (Sandbox Code Playgroud)
但这给了我一个错误:NameError:未定义全局名称'x'
我怎样才能做到这一点?
当我没有明确指定应该使用密钥时,对元组列表(字典键,密钥是随机字符串的值对)进行排序更快(编辑:在@Chepner的评论中添加了operator.itemgetter(0)和密钥版现在更快!):
import timeit
setup ="""
import random
import string
random.seed('slartibartfast')
d={}
for i in range(1000):
d[''.join(random.choice(string.ascii_uppercase) for _ in range(16))] = 0
"""
print min(timeit.Timer('for k,v in sorted(d.iteritems()): pass',
setup=setup).repeat(7, 1000))
print min(timeit.Timer('for k,v in sorted(d.iteritems(),key=lambda x: x[0]): pass',
setup=setup).repeat(7, 1000))
print min(timeit.Timer('for k,v in sorted(d.iteritems(),key=operator.itemgetter(0)): pass',
setup=setup).repeat(7, 1000))
Run Code Online (Sandbox Code Playgroud)
得到:
0.575334150664
0.579534521128
0.523808984422 (the itemgetter version!)
Run Code Online (Sandbox Code Playgroud)
但是,如果我创建一个自定义对象key=lambda x: x[0]显式传递sorted使其更快:
setup ="""
import random
import string
random.seed('slartibartfast')
d={}
class A(object):
def __init__(self):
self.s …Run Code Online (Sandbox Code Playgroud) 我想知道这个%timeit命令IPython
来自文档:
Run Code Online (Sandbox Code Playgroud)%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code选项:
-n:在循环中执行给定的语句次数.如果未给出该值,则选择拟合值.
-r:重复循环迭代次数并获得最佳结果.默认值:3
例如,如果我写:
%timeit -n 250 -r 2 [i+1 for i in range(5000)]
Run Code Online (Sandbox Code Playgroud)
那么,-n 250执行[i+1 for i in range(5000)]250次?那又怎么样-r 2?
timeit.timeit当我在以字符串形式传递的语句参数中有异常时,我似乎无法工作:
# after the first and third semicolon, I put 4 spaces
timeit.timeit('try:; a=1;except:; pass')
Run Code Online (Sandbox Code Playgroud)
这导致:
Traceback (most recent call last):
File "a.py", line 48, in <module>
timeit.timeit('try:; a=1;except:; pass')
File "C:\CPython33\lib\timeit.py", line 230, in timeit
return Timer(stmt, setup, timer).timeit(number)
File "C:\CPython33\lib\timeit.py", line 136, in __init__
code = compile(src, dummy_src_name, "exec")
File "<timeit-src>", line 6
try:; a=1;except:; pass
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我用Python 3.3运行它,但即使使用旧的Python(3.2)也会出现同样的错误.
更新:
我正在关注这个文档(强调我的):
class timeit.Timer(stmt ='pass',setup ='pass',timer =)
用于小代码片段的定时执行速度的类.
构造函数接受一个定时语句,一个用于设置的附加语句和一个定时器函数.两个语句都默认为'pass'; 计时器功能与平台有关(请参阅模块文档字符串).stmt和setup也可能包含多个以;分隔的语句; 或换行符,只要它们不包含多行字符串文字.
我一直在寻求从我的代码中获得更多的性能; 最近,在浏览这个Python维基页面时,我发现了这个主张:
多次分配比单独分配慢.例如,"x,y = a,b"比"x = a; y = b"慢.
好奇,我测试了它(在Python 2.7上):
$ python -m timeit "x, y = 1.2, -1.4"
10000000 loops, best of 3: 0.0365 usec per loop
$ python -m timeit "x = 1.2" "y = -1.4"
10000000 loops, best of 3: 0.0542 usec per loop
Run Code Online (Sandbox Code Playgroud)
我以不同的顺序重复了几次,等等,但多重赋值片段的表现始终比个人作业至少好30%.显然,我的代码涉及变量赋值的部分不会成为任何重大瓶颈的根源,但我的好奇心仍然被激发了.当文档另有说明时,为什么多项任务明显快于个人任务?
编辑:
我测试了两个以上变量的赋值,得到了以下结果:

趋势似乎或多或少一致; 任何人都可以复制它吗?
(CPU:Intel Core i7 @ 2.20GHz)
python performance variable-assignment timeit python-internals
我在16GB,2.7GHz i5,OSX 10.11.5机器上运行Python 2.7.10.
我在许多不同类型的例子中多次观察到这种现象,所以下面的例子虽然有点人为,但具有代表性.这正是我今天早些时候正在努力的事情,当我的好奇心终于被激起时.
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100)
3.790855407714844e-05
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000)
0.0003371238708496094
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=10000)
0.014712810516357422
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100000)
0.029777050018310547
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000000)
0.21139287948608398
Run Code Online (Sandbox Code Playgroud)
您会注意到,从100到1000,正如预期的那样,时间增加了10倍.然而,1e3到1e4,它更像是因子50,然后是从1e4到1e5的因子2(所以从1e3到1e5的总因数为100,这是预期的).
我认为必须在实际的过程中进行某种基于缓存的优化,无论是在实际的过程中还是在timeit本身,但我不能完全根据经验弄清楚是否是这种情况.进口似乎并不重要,可以通过一个最基本的例子来观察:
>>> timeit('1==1', number=10000)
0.0005490779876708984
>>> timeit('1==1', number=100000)
0.01579904556274414
>>> timeit('1==1', number=1000000)
0.04653501510620117
Run Code Online (Sandbox Code Playgroud)
从1e4到1e6,存在1e2时差的真实因子,但中间步长为~30和~3.
我可以做更多临时数据收集,但此时我还没有考虑过假设.
关于为什么非线性标度在某些中间运行次数的任何概念?
我想测量以下代码的执行速度:
def pe1():
l = []
for i in range(1000):
if i%3 == 0 or i%5 == 0:
l.append(i)
print sum(l)
Run Code Online (Sandbox Code Playgroud)
我将此代码存储在pe1m.py下.现在我想用python解释器测试文件的速度.我做了:
import timeit
import pe1m
t = timeit.Timer(stmt = 'pe1m.pe1()')
t.timeit()
Run Code Online (Sandbox Code Playgroud)
但我得到:
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/timeit.py", line 195, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
NameError: global name 'pe1m' is not defined
Run Code Online (Sandbox Code Playgroud)
但我没有任何全局变量.
timeit ×10
python ×9
performance ×2
benchmarking ×1
django ×1
exception ×1
ipython ×1
nameerror ×1
numpy ×1
optimization ×1
python-2.7 ×1
sorting ×1
time ×1
tuples ×1