[英]Calling an overloaded Java method from Jython
当我从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中注释掉第一个方法,那么脚本几乎不需要任何时间。 我很困惑为什么在方法重载时需要这么长时间。 我在这里错过了什么吗?
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)
基本上你要分配大约500000000 bytes
或477 megabytes
500000000 bytes
250x250x250x32 bytes
。 其中 32
是Java中float的大小。 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
的数组!! 拿我用过的代码,然后用20's
改变所有的2's
。
记住为了解决纠正重载函数的问题,jython需要评估[z,z,z]
哪个内存量很大。 这就是你看到延迟的地方。 当您对第一种方法发表评论时,对该调用没有任何混淆,因此它会立即返回。 如果我使用你的代码,那么它首先需要解决上面提到的表达式, 然后计算对象的字符串表示。 结合起来,需要很长时间才能再次响应。 但是,如果我使用代码的修改版本,即x = TestClass.overloaded([z,z,z])
那么它会变得有点快,但仍然需要花时间打印'x'
或者可能导致Heap Exception
!
玩得开心 !!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.