.NET数组在IronPython中比列表慢吗?
我在IronPython中做了一个矩阵乘法的性能测试,参考了这个链接的代码:
from System import Random
from System.Diagnostics import Stopwatch
def zero(m,n):
# Create zero matrix
new_matrix = [[0 for row in range(n)] for col in range(m)]
return new_matrix
def rand(m,n):
# Create random matrix
rnd = Random(1)
new_matrix = [[rnd.NextDouble() for row in range(n)] for col in range(m)]
return new_matrix
def show(matrix):
# Print out matrix
for col in matrix:
print col
def mult(matrix1,matrix2):
# Matrix multiplication
if len(matrix1[0]) != len(matrix2):
# Check matrix dimensions
print 'Matrices must be m*n and n*p to multiply!'
else:
# Multiply if correct dimensions
watch = Stopwatch()
print 'mult1 start....'
watch.Start()
new_matrix = zero(len(matrix1),len(matrix2[0]))
for i in range(len(matrix1)):
for j in range(len(matrix2[0])):
for k in range(len(matrix2)):
new_matrix[i][j] += matrix1[i][k]*matrix2[k][j]
watch.Stop()
print 'mult1 end.'
print watch.ElapsedMilliseconds
return new_matrix
from System import Array
def ListToArray(matrix):
n = len(matrix)
m = len(matrix[0])
a = Array.CreateInstance(float, n, m)
for i in range(n):
for j in range(m):
a[i,j] = matrix[i][j]
return a
def mult2(matrix1, matrix2):
N = len(matrix1)
K = len(matrix2)
M = len(matrix2[0])
m1 = ListToArray(matrix1)
m2 = ListToArray(matrix2)
res = ListToArray(rand(len(matrix1), len(matrix2[0])))
watch = Stopwatch()
print 'mult2 start...'
watch.Start()
for i in range(N):
for j in range(M):
for k in range(K):
res[i,j] += m1[i,k]*m2[k,j]
watch.Stop()
print 'mult2 ends.'
print watch.ElapsedMilliseconds
return res
if __name__ == '__main__':
#a = rand(280,10304)
#b = rand(10304,280)
a = rand(280,10)
b = rand(10,280)
c = mult2(a, b)
d = mult(a, b)
我想尝试两个大矩阵(一个是280行10304列,另一个是10304行208列),但是这两个版本都没法在短时间内得到结果。
然后我试了一个小得多的矩阵(在代码中显示),结果如下:
mult2 : 7902 ms
mult1 : 420 ms
这表明在IronPython中使用.NET数组的速度比使用Python的列表要慢很多。
还注意到C#处理这两个大矩阵大约花了12秒。而IronPython在处理一个小10K倍的案例时已经花了很多时间。我不确定我电脑上的IronPython设置是否有问题,如果没有的话,IronPython在处理数值计算时确实很慢。
4 个回答
当你使用高级编程语言来处理矩阵时,速度可能会慢得让你不满意。 如果你想在 .net 环境下进行矩阵运算,可以试试这个网站 http://numerics.mathdotnet.com/ - 他们已经尽力优化了矩阵操作。
这并不是解释你为什么会看到速度差异的答案,但如果你在寻找快速解决方案,这可能会对你有帮助。
在我们的项目中,我们尽量不使用 .Net 类,直到真的需要的时候才用。我觉得其实没有必要用数组来做矩阵乘法,因为 Python 提供了很多处理矩阵的方法,比如用列表、集合或者 numpy 库。
针对你提到的问题,我觉得主要是因为装箱的原因。在IronPython中,列表里的每个元素(还有其他变量)都是以“装箱”的方式存储的,也就是说,只有经过装箱的值才能被操作。而CLR数组里的元素并不是装箱的,所以当从数组中提取元素时,IronPython需要先把它们装箱,然后在放回去的时候再拆箱。C#可以直接操作那些没有装箱的值,并且有很多其他的优化手段来让数组的操作更快,而这些在IronPython中是没有的。
如果你想进行快速的数值计算,可能NumPy for IronPython会是一个更好的选择。