Python 性能分析:带和不带for循环的解决方案
我用两种不同的解决方案解决了同样的问题,并想知道哪一种更快:使用最少显式循环的numpy逻辑,或者通过迭代数组元素来迭代工作 解决方案1:Python 性能分析:带和不带for循环的解决方案,python,performance,numpy,Python,Performance,Numpy,我用两种不同的解决方案解决了同样的问题,并想知道哪一种更快:使用最少显式循环的numpy逻辑,或者通过迭代数组元素来迭代工作 解决方案1: # see https://stackoverflow.com/questions/27239173/numpy-vectorize-a-parallel-update def function1(cells): assert isinstance(cells, np.ndarray) cells = boundary(cells)
# see https://stackoverflow.com/questions/27239173/numpy-vectorize-a-parallel-update
def function1(cells):
assert isinstance(cells, np.ndarray)
cells = boundary(cells)
center = cells[1:-1]
left = cells[0:-2]
right = cells[2:]
ones = (center == 1)
zeros = (center == 0)
result = np.copy(center)
result[zeros] = left[zeros]
result[ones] = right[ones]
nmoves = sum(np.logical_xor(center, result)) / 2
return result, nmoves
解决方案2:
def function2(actual_cells):
neighbors = np.roll(actual_cells, -1)
assert isinstance(actual_cells, np.ndarray)
dim = len(actual_cells)
num_move = 0
tmp_cells = np.zeros(dim)
for i, j in enumerate(actual_cells):
if j and not neighbors[i]:
tmp_cells[i], tmp_cells[(i + 1) % dim] = 0, 1
num_move += 1
elif j:
tmp_cells[i] = 1
return tmp_cells, num_move
这两种解决方案都根据以下规则计算阵列的新状态(0和1):
Timer unit: 1e-06 s
File: asep.py
Function: asep_parallel at line 113
Total time: 0.488103 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
113 @profile
114 def function1(cells):
120 100 113 1.1 0.0 assert isinstance(cells, np.ndarray)
121 100 1015 10.2 0.2 cells = boundary(cells)
122 100 120 1.2 0.0 center = cells[1:-1]
123 100 81 0.8 0.0 left = cells[0:-2]
124 100 79 0.8 0.0 right = cells[2:]
125 100 537 5.4 0.1 ones = (center == 1)
126 100 401 4.0 0.1 zeros = (center == 0)
127 100 524 5.2 0.1 result = np.copy(center)
128 100 813 8.1 0.2 result[zeros] = left[zeros]
129 100 1303 13.0 0.3 result[ones] = right[ones]
130 100 482996 4830.0 99.0 nmoves = sum(np.logical_xor(center, result)) / 2
131 100 121 1.2 0.0 return result, nmoves
Timer unit: 1e-06 s
及
第一个解决方案99%的时间用于计算移动次数!怎么回事
我将计算移动次数的行替换为
sum(右[个]==0)
只有稍好一些(93.8%)
你知道怎么骑上那条怪物路线吗
编辑:
用np.sum
替换sum
Timer unit: 1e-06 s
File: asep_fast.py
Function: asep_parallel at line 113
Total time: 0.358175 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
113 @profile
114 def asep_parallel(cells):
115 """
116 update of cells
117 :parameter: actual state of cells
118 :rtype : cells with new state and number of moves
119 """
120 10000 9947 1.0 2.8 assert isinstance(cells, np.ndarray)
121 10000 70264 7.0 19.6 cells = boundary(cells)
122 10000 10755 1.1 3.0 center = cells[1:-1]
123 10000 7404 0.7 2.1 left = cells[0:-2]
124 10000 7056 0.7 2.0 right = cells[2:]
125 10000 29433 2.9 8.2 ones = (center == 1)
126 10000 22100 2.2 6.2 zeros = (center == 0)
17 10000 32578 3.3 9.1 result = np.copy(center)
128 10000 31545 3.2 8.8 result[zeros] = left[zeros]
129 10000 24829 2.5 6.9 result[ones] = right[ones]
130 10000 103271 10.3 28.8 nmoves = np.sum(np.logical_xor(center, result)) / 2
131 10000 8993 0.9 2.5 return result, nmoves
如果您使用numpy的
np.sum
而不是python内置,会发生什么情况?@cel:这很有帮助。谢谢请参阅我的编辑。
Timer unit: 1e-06 s
File: asep_fast.py
Function: asep_parallel at line 113
Total time: 0.358175 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
113 @profile
114 def asep_parallel(cells):
115 """
116 update of cells
117 :parameter: actual state of cells
118 :rtype : cells with new state and number of moves
119 """
120 10000 9947 1.0 2.8 assert isinstance(cells, np.ndarray)
121 10000 70264 7.0 19.6 cells = boundary(cells)
122 10000 10755 1.1 3.0 center = cells[1:-1]
123 10000 7404 0.7 2.1 left = cells[0:-2]
124 10000 7056 0.7 2.0 right = cells[2:]
125 10000 29433 2.9 8.2 ones = (center == 1)
126 10000 22100 2.2 6.2 zeros = (center == 0)
17 10000 32578 3.3 9.1 result = np.copy(center)
128 10000 31545 3.2 8.8 result[zeros] = left[zeros]
129 10000 24829 2.5 6.9 result[ones] = right[ones]
130 10000 103271 10.3 28.8 nmoves = np.sum(np.logical_xor(center, result)) / 2
131 10000 8993 0.9 2.5 return result, nmoves