Skip to main content
 首页 » 编程设计

Python:非常慢的执行循环

2025年05月04日14exmyth

我正在编写一个代码,用于使用 HMM 和维特比算法提出拼写错误更正建议。在某些时候,对于文本中的每个单词,我必须执行以下操作。 (假设我有 10,000 个单词)

#FYI Windows 10, 64bit, interl i7 4GRam, Python 2.7.3 
import numpy as np 
import pandas as pd 
 
for k in range(10000): 
    tempWord = corruptList20[k] #Temp word read form the list which has all of the words 
    delta = np.zeros(26, len(tempWord))) 
    sai = np.chararray(26, len(tempWord))) 
    sai[:] = '@' 
 
    # INITIALIZATION DELTA 
    for i in range(26): 
        delta[i][0] = #CALCULATION matrix read and multiplication each cell is different 
    # INITILIZATION END 
 
    # 6.DELTA  CALCULATION 
    for deltaIndex in range(1, len(tempWord)): 
        for j in range(26): 
            tempDelta = 0.0 
            maxDelta = 0.0 
            maxState = '' 
            for i in range(26): 
                # CALCULATION to fill each cell involve in: 
                   # 1-matrix read and multiplication 
                   # 2 Finding Column Max 
                   # logical operation and if-then-else operations 
 
    # 7. SAI BACKWARD TRACKING 
    delta2 = pd.DataFrame(delta) 
    sai2 = pd.DataFrame(sai) 
 
    proposedWord = np.zeros(len(tempWord), str) 
    editId = 0 
    for col in delta2.columns: 
         # CALCULATION to fill each cell involve in: 
                # 1-matrix read and multiplication 
                # 2 Finding Column Max 
                # logical operation and if-then-else operations 
         editList20.append(''.join(editWord)) 
#END OF LOOP 

如您所见,它涉及计算,当我运行时,它需要花费太多时间才能运行。 目前我的笔记本电脑被盗,我在 Windows 10、64 位、4GRam、Python 2.7.3 上运行它

我的问题:任何人都可以看到我可以用来优化的任何点吗?在循环进入下一轮之前,我是否必须删除我在循环中创建的矩阵以释放内存,还是自动完成?

在下面的评论和使用 xrange 而不是 range 之后,性能几乎提高了 30%。在此更改后,我将在此处添加屏幕截图。

请您参考如下方法:

我不认为 range 的讨论有什么不同。在 Python3 中,range 是迭代器,在迭代前将其扩展为列表不会改变太多时间。

In [107]: timeit for k in range(10000):x=k+1 
1000 loops, best of 3: 1.43 ms per loop 
 
In [108]: timeit for k in list(range(10000)):x=k+1 
1000 loops, best of 3: 1.58 ms per loop 

使用 numpy 和 pandas 加速循环的真正关键是将它们替换为适用于整个数组或数据帧的编译操作。但即使在纯 Python 中,也应专注于精简迭代的内容,而不是迭代机制。

======================

for i in range(26): 
    delta[i][0] = #CALCULATION matrix read and multiplication 

一个小改动:delta[i, 0] = ...;这是寻址单个元素的数组方式;在功能上它通常是相同的,但意图更清楚。但是想一想,您不能将所有该列设置为一次吗?

delta[:,0] = ... 

====================

N = len(tempWord) 
delta = np.zeros(26, N)) 
etc 

在紧密循环中,像这样的临时变量可以节省时间。这并不严密,所以这里只是为了增加清晰度。

===========================

这个丑陋的嵌套三重循环;诚然 26 步并不大,但 26*26*N 是:

for deltaIndex in range(1,N): 
    for j in range(26): 
        tempDelta = 0.0 
        maxDelta = 0.0 
        maxState = '' 
        for i in range(26): 
            # CALCULATION  
               # 1-matrix read and multiplication 
               # 2 Finding Column Max 
               # logical operation and if-then-else operations 

专注于用数组操作替换它。需要更改的是那 3 行注释,而不是迭代机制。

================

使 proposedWord 成为列表而不是数组可能会更快。小型列表操作通常比数组操作更快,因为 numpy 数组有创建开销。

In [136]: timeit np.zeros(20,str) 
100000 loops, best of 3: 2.36 µs per loop 
 
In [137]: timeit x=[' ']*20 
1000000 loops, best of 3: 614 ns per loop 

创建“空”列表时必须注意元素是真正独立的,而不仅仅是同一事物的副本。

In [159]: %%timeit                       
x = np.zeros(20,str) 
for i in range(20): 
   x[i] = chr(65+i) 
   .....:  
100000 loops, best of 3: 14.1 µs per loop 
 
In [160]: timeit [chr(65+i) for i in range(20)] 
100000 loops, best of 3: 7.7 µs per loop