从 Jython 调用重载的 Java 方法

发布于 2025-01-08 15:09:37 字数 692 浏览 1 评论 0原文

当我从 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 中的第一个方法,该脚本几乎不需要任何时间。我很困惑为什么当方法重载时需要花费这么长时间。我在这里错过了什么吗?

I'm seeing some strange behavior I don't understand when I call an overloaded Java method from a Jython script.

Here is my Java class:

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];
  }
}

and here is my Jython script:

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)

This Jython script takes about 1 minute to run, but if I comment out the first method in TestClass the script takes almost no time at all. I'm confused why it takes so much longer when the method is overloaded. Am I missing something here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷︶言冷语的世界 2025-01-15 15:09:37

你的代码!

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) 时> 那么本质上你分配的250x250x250x32字节大约是500000000字节477 兆字节其中 32是Java中浮点数的大小。
  3. 当你说 TestClass.overloaded([z,z,z]) 时,你总是会调用 4 维重载方法!不信就试试吧!!

我的代码工作正常!

我刚刚将 TestClass.overloaded([z,z,z]) 更改为 x = TestClass.overloaded([z,z,z])。而且执行速度非常快。但是在打印'x'它仍然失败!!为什么?!

“为什么”部分!

它会失败,因为当您执行 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

输出:

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字节!拿我用过的代码,然后将所有 2's 更改为 20's

但是,当您不取消第一个方法的注释时,为什么要花时间!

请记住,为了解决正确的重载函数,jython 需要评估 [z,z,z] 这是大量内存。这就是你看到延迟的地方。当您注释第一个方法时,调用就不会混淆,因此它会立即返回。如果我使用您的代码,那么首先需要解析上述表达式,然后然后计算对象的字符串表示形式。综合起来,需要很长时间才能再次做出反应。但是,如果我使用代码的修改版本,即 x = TestClass.overloaded([z,z,z]) 那么它会变得更快一点,但在打印 ' 时仍然需要时间x' 或可能导致堆异常

玩得开心 !!

Your Code !!

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)

Facts !!

  1. Jython is Java based (well we already know that !!)
  2. When you do n1,n2,n3 = 250,250,250 and say z = TestClass.zeros(n1,n2,n3) then essentially you are allocating 250x250x250x32 bytes that is around 500000000 bytes or 477 megabytes. Where 32 is the size of float in Java.
  3. When you say TestClass.overloaded([z,z,z]) then you are always going to call the 4 dimensional overloaded method !! Try it if you don't believe me !!

My code works fine !!

I just changed the TestClass.overloaded([z,z,z]) to x = TestClass.overloaded([z,z,z]). And the execution was really fast. But on printing 'x' it still fails!! why ?!

The 'why' part !!

It fails because when you do TestClass.overloaded([z,z,z]) or when I print 'x' because python or rather jython needs to convert the object in string representation and that is where the problem lies. See the stacktrace below:

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)

See.. The JVM is bombed !!!! Its out of heap space... Even if you change the JVM argument for memory and bless this program with more, even then your talking about 478 MB !! (Well it is not just 478 MB because you are passing an array of 'z' and each one of them is 478 MB !!!) and that is just what you have allocated, besides that JVM will need memory for the StringBuilder to save the string representation and some other things!!

And believe me it will take time and a good amount of time.

Just to give you some feel !!

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

See the size of string and it is just for 2x2x2x32 bytes of array !! Take the code I have used and then change all the 2's with 20's.

But why it is taking time when you don't uncomment the first method !!!

Remember in order to resolve to correct overloaded function jython needs to evaluate the [z,z,z] which is good amount of memory. And that is where you are seeing that delay. When you comment the first method then there is no confusion about the call and hence it return instantaneously. If I use your code then it first takes to resolve the above mentioned expression and then calculate the string representation of the object. Combined, it will take long to become responsive again. But, if I use the modified version of your code i.e. x = TestClass.overloaded([z,z,z]) then it becomes a bit faster but will still take time in printing 'x' or may result in Heap Exception !!

Have fun !!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文