索引Numpy ndarray的性能比(Python)列表差吗?
一些背景。为了解决Sudoku的问题,我将问题转换为精确的掩盖问题,并使用Knuth的“ algorithm X”在Python中解决了问题,但是(显然吗?)没有跳舞链接。一切似乎都不错,但与更传统的回溯搜索和弧形一致性相比较,性能却有些慢。大约75%的时间花费在我称为“ cover”的函数上。基本上,列表索引的确很多。由于Python列表是作为指向Python对象的指针的动态数组实现的,而Numpy ndarrays是具有所有大小都相同的固定大小的数组(如C数组),所以我认为将Python列表转换为ndarray可以加快程序的速度。
import numpy as np
def cover(row_valid, col_valid):
for cnt in range(10000):
for j,v in enumerate(row[20]):
if v == 1:
# for all values = 1 in row r set col c invalid
col_valid[j] = 1 # hack
# for all valid rows r': if row[r][i] == 1 and row[r'][i] == 1:
# set row r' invalid (this includes r itself)
for row_idx, valid in enumerate(row_valid):
if valid == 1: # if row is valid
if row[row_idx][j] == 1:
row_valid[row_idx] = 1 # hack
# version with Python lists
row = [[0 for c in range(100)] for r in range(100)]
row_valid = 100 * [1]
col_valid = 100 * [1]
# version with Numpy ndarrays
row = np.zeros((100, 100), dtype=np.uint8)
row_valid = np.ones(100, dtype=np.uint8)
col_valid = np.ones(100, dtype=np.uint8)
# run both versions using
import time
start_time = time.time()
cover(row_valid, col_valid)
end_time = time.time()
hrs, rem = divmod(end_time-start_time, 3600)
mins, secs = divmod(rem, 60)
print("duration [hh:mm:ss]: {:0>2}:{:0>2}:{:05.2f}".format(int(hrs),int(mins),secs))
print()
功能封面没有做任何有用的事情,我对其进行了一些修改以使其可重复。但是结构与原始结构相同。
Numpy ndarray版本大约比list版本慢25倍。任何想法为什么会这样?有没有办法改善功能罩的性能?