Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/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_Iteration - Fatal编程技术网

Python 多次迭代的性能

Python 多次迭代的性能,python,performance,iteration,Python,Performance,Iteration,想知道一次迭代与多次迭代对性能的影响。我使用Python——我不确定这是否会影响答案 考虑尝试对列表中的每个项目执行一系列数据转换 def one_pass(my_list): for i in xrange(0, len(my_list)): my_list[i] = first_transformation(my_list[i]) my_list[i] = second_transformation(my_list[i]) my_lis

想知道一次迭代与多次迭代对性能的影响。我使用Python——我不确定这是否会影响答案

考虑尝试对列表中的每个项目执行一系列数据转换

def one_pass(my_list):
    for i in xrange(0, len(my_list)):
        my_list[i] = first_transformation(my_list[i])
        my_list[i] = second_transformation(my_list[i])
        my_list[i] = third_transformation(my_list[i])
    return my_list

def multi_pass(my_list):
    range_end = len(my_list)
    for i in xrange(0, range_end):
       my_list[i] = first_transformation(my_list[i])

    for i in xrange(0, range_end):
       my_list[i] = second_transformation(my_list[i])

    for i in xrange(0, range_end):
       my_list[i] = third_transformation(my_list[i])

    return my_list

现在,除了可读性问题外,严格从性能方面来说,一次传递比多次传递有真正的优势吗?假设大部分工作发生在转换函数本身中,那么多次迭代中的每次迭代不会花费大约1/3的时间吗?

与另一个版本相比,两个版本中的缓存未命中率都会降低。这取决于这些变换函数的实际功能

如果这些函数有很多代码,并且对不同的数据集(除了输入和输出)进行操作,那么多路径可能更好。否则,单次传递可能会更好,因为当前列表元素可能会保持缓存状态,并且循环操作只执行一次而不是三次


这是一个比较实际运行时间非常有用的例子。

就我个人而言,我无疑更喜欢一次通过选项。它确实表现得更好。你可能是对的,差别不会很大。Python对xrange迭代器进行了很好的优化,但您的迭代次数仍然比需要的多3倍。

不同之处在于您读取的值和代码在该文件中的频率

如果
my_list
的元素很大,但适合CPU缓存,那么第一个版本可能会很有用。另一方面,如果转换的(字节)代码很大,则缓存操作可能比缓存数据要好

这两个版本可能都比可读性更强的方式慢:

def simple(my_list):
    return [third_transformation(second_transformation(first_transformation(e)))
            for e in my_list]
收益率:


假设您正在考虑一个程序,该程序很容易成为一个包含多个操作的循环,或者多个循环分别执行一个操作,那么它永远不会改变计算复杂性(例如,无论哪种方式,O(n)算法仍然是O(n))

单通道方法的一个优点是可以节省循环的“簿记”。无论迭代机制是递增和比较计数器,还是检索“下一个”指针并检查null,或者其他什么,当您在一个过程中完成所有操作时,您所做的事情都会更少。假设您的操作完成了大量的工作(并且您的循环机制简单明了,没有在昂贵的生成器上循环),那么这个“簿记”工作将与您操作的实际工作相形见绌,这使得这绝对是一个微观优化,你不应该这样做,除非你知道你的程序太慢,你已经用尽所有更重要的可用优化

另一个优点是,在进入下一个迭代之前,将所有操作应用于迭代的每个元素,往往会更好地受益于CPU缓存,因为在同一个项目的后续操作中,每个项目都可能仍在缓存中,而使用多个过程几乎不可能做到这一点(除非你的整个集合都放在缓存中)。Python通过字典进行了大量的间接操作,但通过读取散落在内存空间中的散列桶,每个操作可能都不难溢出缓存。因此,这仍然是一个微观优化,但此分析为它提供了更多的机会(尽管仍然不确定)产生重大影响

多过程的一个优点是,如果您需要在循环迭代之间保持状态,单过程方法会强制您保持所有操作的状态。这可能会损害CPU缓存(可能每个操作的状态单独适合整个过程的缓存,但不是所有操作的状态)。在极端情况下,理论上,这种效应可能会导致程序在内存中的匹配与否发生差异(我曾在一个处理大量数据的程序中遇到过这种情况).但在极端情况下,你知道你需要将事情分解,而非极端情况又是不值得提前进行的微观优化

因此,性能通常只支持少量的单次传递,但在某些情况下,可以支持大量的单次传递或多次传递只有当你完成了一个基本完成的程序,如果它“不够快”,然后测量代码各个部分的性能影响,找出值得花费时间的地方


出于性能原因而担心是否编写单过程或多过程算法的时间几乎总是浪费掉了。因此,除非您有无限的开发时间,否则您将从总体开发工作中获得“最佳”结果(最佳包括性能)如果大部分工作都发生在转换函数中,那么你已经回答了你自己的问题-单程方法没有效率优势。顺便说一句,如果有疑问,请测量!顺便说一句,它可能应该是
xrange(len(我的列表))
,不减去一。
xrange
默认情况下生成闭合-打开间隔。@user4815162342--关于xrange(),您是对的。进行了更正。
one_pass: 0.839533090591
multi_pass: 0.840938806534
simple: 0.569097995758