当我从Jython脚本调用重载的Java方法时,我看到一些我不理解的奇怪行为。
这是我的Java类:
public class TestClass {
public static float[][][] overloaded(float[][][] x) {
return x;
}
public static float[][][][] overloaded(float[][][][] x) {
return x;
}
public static float[][][] zeros(int n1, int n2, int n3) {
return new float[n3][n2][n1];
}
}
这是我的Jython脚本:
import time,TestClass
n1,n2,n3 = 250,250,250
z = TestClass.zeros(n1,n2,n3)
start = time.time()
TestClass.overloaded([z,z,z])
print 'time =',(time.time()-start)
这个Jython脚本大约需要1分钟才能运行,但是如果我在TestClass中注释掉第一个方法,那么脚本几乎不需要时间。我很困惑为什么在方法重载时需要这么长时间。我在这里错过了什么吗?
答案 0 :(得分:3)
import time,TestClass
n1,n2,n3 = 250,250,250
z = TestClass.zeros(n1,n2,n3)
start = time.time()
TestClass.overloaded([z,z,z])
print 'time =',(time.time()-start)
n1,n2,n3 = 250,250,250
并说z = TestClass.zeros(n1,n2,n3)
时,基本上您正在分配250x250x250x32 bytes
或500000000 bytes
周围的477 megabytes
。 32
是Java中浮点数的大小。TestClass.overloaded([z,z,z])
时,你总是会打电话给4维重载方法!!如果你不相信我,试试吧!! 我刚刚将TestClass.overloaded([z,z,z])
更改为x = TestClass.overloaded([z,z,z])
。执行速度非常快。但是在打印'x' it still fails!!
为什么?!
它失败,因为当你做TestClass.overloaded([z,z,z])
或者当我打印'x'
因为Python或Jython的,而需要将对象转换成字符串表示,这就是问题所在。请参阅下面的堆栈跟踪:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuilder.toString(StringBuilder.java:430)
at org.python.core.PyList.list_toString(PyList.java:472)
at org.python.core.PyList.toString(PyList.java:450)
at org.python.core.PyArray.toString(PyArray.java:395)
at org.python.core.PyObject.__repr__(PyObject.java:174)
at org.python.core.PyList.list_toString(PyList.java:464)
at org.python.core.PyList.toString(PyList.java:450)
at org.python.core.PyArray.toString(PyArray.java:395)
at org.python.core.PyObject.__repr__(PyObject.java:174)
请参阅.. JVM遭到轰炸!!!!它的堆空间了......即使你改变了JVM参数的内存和更多的祝福这个程序,即使这样你谈论的的 478 MB !!
的 (当然它不只是478 MB
,因为要传递的阵列'z'
,并将它们中的每一个是478 MB
!!!) 强>那是只是你分配的内容,除了JVM需要内存StringBuilder
来保存字符串表示和其他一些东西!
相信我需要时间和时间。
>>> n1,n2,n3 = 2,2,2
>>> z = TestClass.zeros(n1,n2,n3)
>>> x = TestClass.overloaded([z,z,z])
>>> x
的 Output:
强> 的
array([[[F, [array([[F, [array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0
])]), array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0])])]), array([[F,
[array([F, [array('f', [0.0, 0.0]), array('f', [0.0, 0.0])]), array([F, [array('
f', [0.0, 0.0]), array('f', [0.0, 0.0])])]), array([[F, [array([F, [array('f', [
0.0, 0.0]), array('f', [0.0, 0.0])]), array([F, [array('f', [0.0, 0.0]), array('
f', [0.0, 0.0])])])])
查看字符串的大小,它只适用于数组的2x2x2x32 bytes
!获取我使用的代码,然后使用2's
更改所有20's
。
请记住,为了解决纠正重载函数的问题,jython需要评估[z,z,z]
哪个内存量很大。这就是你看到延迟的地方。当您对第一种方法发表评论时,对该调用没有任何混淆,因此它会立即返回。如果我使用您的代码,则首先用于解析上述表达式,然后然后计算对象的字符串表示形式。结合起来,需要很长时间才能再次响应。但是,如果我使用代码的修改版本,即x = TestClass.overloaded([z,z,z])
,那么它会变得有点快,但仍然需要花时间打印'x'
或者可能会导致Heap Exception
!
玩得开心!!