好的,我试着阅读了几个来源:一,二,三。第一个源明确指出,使用生成器表达式可以节省内存,使事情更快。但是当它们被嵌套时会发生什么呢?这里有一个例子,我希望有人能帮助我理解它。
In [1]: def nested():
[(ix, '-'.join(str(x) for x in hours)) for ix in table.index.get_level_values(0)]
%timeit nested
Out [1]: 10000000 loops, best of 3: 33.5 ns per loop
In [2]: def not_nested():
hr = '-'.join(str(x) for x in hours) #hr = 7-8
[(ix, hr) for ix in table.index.get_level_values(0)]
%timeit not_nested
Out [2]: 10000000 loops, best of 3: 38.7 ns per loop在上面的示例中,hours是一个list 2元素,而table中0级的索引数是32。
如果我要在我的头脑中运行这两个函数,我会假设在函数nested中,元组('-'.join(str(x) for x in hours)的后半部分将被调用的次数与‘ix’(ix)循环运行的次数相同(即table中有索引的次数)。但是,在函数not_nested中,元组的后半部分只初始化一次(存储在hr中),并且不会每次执行第二行时运行。
首先,我是否正确地认为Python就是这样工作的?如果我是,那么有人能解释为什么嵌套函数的运行时间比非嵌套函数的运行时间短吗?
Begin编辑/解决方案
显然,我在调用这个函数时犯了一个错误,因为这两个答案启发了我。我用正确的函数调用重新运行了timeit,并得到了预期的结果:
In [1]: %timeit nested()
Out [1]: 10000 loops, best of 3: 55.5 µs per loop
In [2]: %timeit not_nested()
Out [2]: 100000 loops, best of 3: 4.53 µs per loop最终,将未嵌套的运行时设置为嵌套时运行时的一小部分。感谢所有的回答和清除这一切!
端编辑
发布于 2014-09-01 08:24:43
您不是在测量调用函数的时间,而是度量在当前作用域中查找函数名称的时间。
试试%timeit nested()。
至于为什么时间有差异--很容易说“因为第二个名字更长,所以哈希查找中的字符串比较需要更长的时间”,但我不认为这实际上是正确的,因为(我认为)所涉及的字符串无论如何都会被CPython嵌入。当然,我不能让Python在我自己的测试中报告更长的查找更长函数名的时间。
如果您对查找时间感兴趣,那么先多运行一次,看看数字有多一致。
发布于 2014-09-01 08:30:23
您正在计时从名称空间检索函数所需的时间。名称空间是一个字典,为了在字典中搜索某些内容,python必须在键(函数名)上调用hash函数。
较长的键需要更多的时间来生成哈希,所以您看到的增量是因为nested是6个字母,而not_nested是10个字母。尝试切换名称,神奇地,较慢的功能将变得更快,根据您的测试。为了对函数进行计时,您必须调用它:
%timeit nested()
%timeit not_nested()https://stackoverflow.com/questions/25601279
复制相似问题