Вызов перегруженного Java-метода из Jython - PullRequest
5 голосов
/ 25 февраля 2012

Я вижу странное поведение, которое я не понимаю, когда вызываю перегруженный Java-метод из скрипта Jython.

Вот мой класс 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, сценарий почти не тратит время.Я запутался, почему это так долго, когда метод перегружен.Я что-то здесь упускаю?

1 Ответ

3 голосов
/ 02 марта 2012

Ваш код !!

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 bytes, что составляет 500000000 bytes или 477 megabytes. Где 32 - это размер числа с плавающей точкой в ​​Java.
  3. Когда вы говорите TestClass.overloaded([z,z,z]), вы всегда будете вызывать4-х мерный перегруженный метод !!Попробуй, если не веришь !!

Мой код работает нормально !!

Я только что изменил TestClass.overloaded([z,z,z]) на x = TestClass.overloaded([z,z,z]).И казнь была действительно быстрой.Но при печати 'x' it still fails!! почему?!

Часть «почему» !!

Itтерпит неудачу, потому что когда вы делаете 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], что хорошоколичество памяти.И именно здесь вы видите эту задержку.Когда вы комментируете первый метод, тогда нет никакого замешательства в отношении вызова, и, следовательно, он мгновенно возвращается.Если я использую ваш код, то first требуется для разрешения вышеупомянутого выражения, а затем вычисляет строковое представление объекта.В совокупности потребуется много времени, чтобы снова стать отзывчивым.Но если я использую модифицированную версию вашего кода, то есть x = TestClass.overloaded([z,z,z]), тогда она станет немного быстрее, но все равно потребуется время для печати 'x' или может привести к Heap Exception !!

Веселитесь !!

...