繁体   English   中英

从Jython调用重载的Java方法

[英]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)

事实!!

  1. Jython是基于Java的(我们已经知道!!)
  2. 当你执行n1,n2,n3 = 250,250,250并且说z = TestClass.zeros(n1,n2,n3)基本上你要分配大约500000000 bytes477 megabytes 500000000 bytes 250x250x250x32 bytes 其中 32是Java中float的大小。
  3. 当你说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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM