Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:列表理解与映射_Python_Performance - Fatal编程技术网

Python:列表理解与映射

Python:列表理解与映射,python,performance,Python,Performance,关于这个问题,有人能解释为什么当列表理解不调用函数时,列表理解会比map产生更好的结果,即使map中没有lambda函数,但调用函数时会产生最差的结果 import timeit print timeit.Timer('''[i**2 for i in xrange(100)]''').timeit(number = 100000) print timeit.Timer('''map(lambda i: i**2, xrange(100))''').timeit(number = 10000

关于这个问题,有人能解释为什么当列表理解不调用函数时,列表理解会比
map
产生更好的结果,即使
map
中没有lambda函数,但调用函数时会产生最差的结果

import timeit

print timeit.Timer('''[i**2 for i in xrange(100)]''').timeit(number = 100000)

print timeit.Timer('''map(lambda i: i**2, xrange(100))''').timeit(number = 100000)

print timeit.Timer(setup="""def my_pow(i):
    return i**2
""",stmt="""map(my_pow, xrange(100))""").timeit(number = 100000)

print timeit.Timer(setup="""def my_pow(i):
    return i**2
""",stmt='''[my_pow(i) for i in xrange(100)]''').timeit(number = 100000)
结果:

1.03697046805 <-- list comprehension without function call
1.96599485313 <-- map with lambda function
1.92951520483 <-- map with function call
2.23419570042 <-- list comprehension with function call

1.03697046805所有计时结果都可以用以下事实来解释:

  • CPython有相当高的函数调用开销

  • map(f,it)
    略快于
    [f(x)for x in it]


  • 代码的第一个版本根本没有定义函数,因此没有函数调用开销。第二个版本需要定义一个函数,因此在每次迭代中都有函数调用开销。第三个版本与第二个版本完全相同–函数和lambda表达式是相同的。根据事实2,最后一个版本更慢。

    无论在
    map
    中调用的函数是lambda函数还是常规函数,开销仍然存在。不知道为什么一个函数调用的列表理解会比
    map()
    慢。@millimoose但是lambda函数会为每个itetaration声明,这会有任何变化吗?@zenpoy:函数调用参数会在调用函数之前计算,因此函数只声明一次。无法删除对我phine的注释:(@SvenMarnach我想他/她说的是
    my_pow
    定义在整个执行过程中只解释一次(在设置中)每个迭代都定义了lambda。这是一个有效的问题,lambda可能导致它的版本稍微慢一些。我可以想到两个可能的原因(2):
    map
    的循环直接在C中进行,因此循环中的开销稍微小一些,对于
    map
    而言,对名称
    f
    的引用只需要解决一次,但是对于列表理解,每次迭代都需要解决一次。第二次对我来说更重要,但是有没有办法告诉我哪一次贡献更大?@Dougal:这是n这是第一次有人提到C中的循环,但我从未找到一个引用或其他东西来替代它应该更快。@RikPoggi我试着检查Python源代码,3.x中的
    map
    实际上返回了一个迭代器,并继续使用参数的迭代器,这使得这一理论不太可能所有这些都是基于C的,可能会节省一些成本,但C中没有神秘的“循环”。在这方面比较2.x和3.x的性能可能会很有趣(如果不是决定性的话)。@millimoose:类似“循环完全是在C中完成的”之类的事情通常意味着执行循环不需要Python字节码求值。@SvenMarnach很公平,但是这种区别会有显著的区别吗?运行时仍然需要处理所有操作解释器状态的开销;在我看来,字节码分派本身并不是主要的贡献者经济放缓。