Votre 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)
Les faits ! !
- Jython est basé sur Java (nous le savons déjà ! !).
- Quand vous le faites
n1,n2,n3 = 250,250,250
et dire z = TestClass.zeros(n1,n2,n3)
alors vous allouez essentiellement 250x250x250x32 bytes
qui est autour de 500000000 bytes
o 477 megabytes
. Où 32
est la taille d'un flottant en Java.
- Quand vous dites
TestClass.overloaded([z,z,z])
alors vous allez toujours appeler la méthode surchargée en 4 dimensions ! !! Essayez-le si vous ne me croyez pas ! !
Mon code fonctionne bien !
Je viens de changer le TestClass.overloaded([z,z,z])
a x = TestClass.overloaded([z,z,z])
. Et l'exécution a été très rapide. Mais à l'impression 'x' it still fails!!
Pourquoi ? !
La partie "pourquoi" !
Il échoue parce que lorsque vous faites TestClass.overloaded([z,z,z])
ou lorsque j'imprime 'x'
parce que python ou plutôt jython doit convertir l'objet en représentation de chaîne de caractères et c'est là que le problème se situe. Voir le stacktrace ci-dessous :
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)
Voyez ... La JVM est bombardée ! !!! Il n'y a plus d'espace dans le tas... Même si vous changez l'argument de la JVM pour la mémoire et bénissez ce programme avec plus, même alors vous parlez de 478 MB !!
(Eh bien, ce n'est pas seulement 478 MB
car vous passez un tableau de 'z'
et chacun d'entre eux est 478 MB
! !!) et c'est juste ce que vous avez alloué, en plus du fait que la JVM aura besoin de mémoire pour les StringBuilder
pour sauvegarder la représentation de la chaîne de caractères et quelques autres choses !
Et croyez-moi, cela prendra du temps et une bonne quantité de temps.
Juste pour vous donner une idée !
>>> 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])])])])
Voir la taille de la chaîne de caractères et c'est juste pour 2x2x2x32 bytes
du tableau ! ! Prenez le code que j'ai utilisé et changez tous les éléments du tableau. 2's
con 20's
.
Mais pourquoi cela prend du temps alors que vous ne décommentez pas la première méthode ! !!
Rappelez-vous que, pour résoudre la fonction surchargée correcte, jython doit évaluer la fonction [z,z,z]
ce qui est une bonne quantité de mémoire. Et c'est là que vous voyez ce retard. Lorsque vous commentez la première méthode, il n'y a pas de confusion sur l'appel et donc le retour est instantané. Si j'utilise votre code, alors il premièrement prend pour résoudre l'expression susmentionnée et puis calcule la représentation en chaîne de l'objet. Combiné, il mettra longtemps à redevenir réactif. Mais, si j'utilise la version modifiée de votre code, à savoir x = TestClass.overloaded([z,z,z])
alors cela devient un peu plus rapide mais cela prendra toujours du temps à l'impression. 'x'
ou peut entraîner Heap Exception
! !
Amusez-vous bien ! !