Code récursif s’exécutant lentement sur la boîte UNix mais rapide sur Windows

J’ai un code java qui est la combinaison de la boucle while et de la récursivité. Le problème auquel nous sums confrontés est que l’appel à la méthode ci-dessous prend près de 8 fois plus de temps sur un boîtier unix [HP ProLiant BL460c G7] qu’un boîtier Windows [processeur Intel Xeon E5-1650, Windows 7 64 bits]. Toutes les idées sur la façon d’améliorer le temps d’exécution dans la boîte Unix. Nous utilisons JDK 1.6_43 [64 bits]

protected Date abc(int n, Date date) { long tStart = System.currentTimeMillis(); if (n > 0) { while (n > 0) { --n; date = getNextExchangeDateUnadjusted(date); } return date; } else { Date nextExchangeDate = getNextExchangeDateUnadjusted(date); Date previousExchangeDate = getNextExchangeDateUnadjusted(date); while (!abc( -n + 1, previousExchangeDate).equals(nextExchangeDate)) { date = date.addDays( -14); previousExchangeDate = getNextExchangeDateUnadjusted(date); } return previousExchangeDate; } } 

MODIFIER:

Voici le code de la méthode getNextExchangeDateUnadjusted appelée ci-dessus

 public Date getNextExchangeDateUnadjusted(Date date) { // Third Wednesday of each month Date thirdWednesdayInMonth = date.getThirdWednesdayInMonth(); if (thirdWednesdayInMonth.after(date)) { return thirdWednesdayInMonth; } return date.addMonths(1).getThirdWednesdayInMonth(); } } 

Vous souhaitez également append que le code passe le temps maximum dans cette partie:

  while (!abc( -n + 1, previousExchangeDate).equals(nextExchangeDate)) { date = date.addDays( -14); previousExchangeDate = getNextExchangeDateUnadjusted(date); } 

EDIT2:

Nous avons pris plusieurs sauvegardes de tas sur le boîtier Unix au fur et à mesure de l’avancement du processus et avons constaté que «Retained Heap» commençait à augmenter d’environ 1 Mo à 4,5 Mo, de sorte que la taille de la stack augmente considérablement. Pas sûr si cela conduira à une performance lente. Nous allons maintenant prendre des vidages de tas dans Windows et allons également essayer de changer la taille de la stack avec XSS.

Une approche à plusieurs volets a été adoptée pour résoudre ce problème:

  1. Nous avons exclu tout appel d’office ou appel distant provoquant des retards inutiles.
  2. Des vidages de tas ont été effectués via Visual VM pour voir tout comportement inhabituel dans le processus et une comparaison a été effectuée entre Unix et Windows. Tout ce que nous pouvions tracer ici était que le thread principal occupait 4,5 Mo d’espace de stack, mais il en était de même pour Unix et Windows.
  3. La seule option qui restait à présent était de voir s’il y avait des lacunes dans JVM sur Unix et Windows et s’il y avait des écarts d’optimisation entre les 2.

Le problème a été repéré en 3 parties, l’écart suivant a été observé lorsque nous avons exécuté la commande java -version

  • Sous Windows

    version java “1.6.0_43”

    Java (TM) SE Runtime Environment (version 1.6.0_43-b01)

    VM serveur Java HotSpot (64 bits) (version 20.14-b01, mode mixte)

  • Sur Unix

    version java “1.6.0_43”

    Java (TM) SE Runtime Environment (version 1.6.0_43-b01)

    VM serveur Java HotSpot (64 bits) (version 20.14-b01, mode interprété)

Vous pouvez voir la différence nette entre le mode hotspot JVM entre unix et windows. Lors d’autres investigations, nous avons constaté que JVM s’exécutant dans Interpreted n’optimise pas le code. jvm-types-and-comstackr-modes / ]. Nous avons donc commencé notre processus sur la boîte Unix avec l’indicateur -Xmixed qui a forcé JVM à travailler en mode mixte. Cela a résolu notre problème et les performances d’Unix et de Windows sont devenues les mêmes.

MODIFIER:

JVM était poussé en mode interprété à cause de ce paramètre dans la case unix: -Djava.comstackr=NONE

Je vous suggère de prendre d’abord un stylo et du papier pour corriger la logique de votre code.

J’ai suivi pour vous

 assume abc is initially called as abc(1, "date < 3th Wednesday") it will return "3th Wednesday in the same month" assume abc is initially called as abc(0, "date < 3th Wednesday") 1. while loop iteration abc(1, 3th Wednesday in the same month) - return 3th Wednesday of month+1 - as this is not equal with the "3th Wednesday in the same month" (nextExchangeDate) you compute "date - 14 day" 2. while loop iteration abc will be called as abc(1, "date - 14 day") which return "3th Wednesday of month-1" 3. while loop iteration abc will be called as abc(1, "3th Wednesday of month-1") ... 

Là je me suis arrêté. Cela ressemble plus à des essais et des erreurs que des calculs. Je voudrais d'abord résoudre ce problème avant de rechercher les différences de performances.

Ok voici un exemple de calcul

avec date de début "16.11.2015" et n = 1

 abc(1, 16.11.2015) 16.11.2015 get 3th Wed ==> 18.11.2015 abc date: 18.11.2015 

avec date de début "16.11.2015" et n = 0

 abc(0, 16.11.2015) 16.11.2015 get 3th Wed ==> 18.11.2015 16.11.2015 get 3th Wed ==> 18.11.2015 abc(1, 18.11.2015) 18.11.2015 get 3th Wed ==> 18.11.2015 18.11.2015 + (1) month 18.12.2015 get 3th Wed ==> 16.12.2015 16.11.2015 + (-14) days 02.11.2015 get 3th Wed ==> 18.11.2015 abc(1, 18.11.2015) 18.11.2015 get 3th Wed ==> 18.11.2015 18.11.2015 + (1) month 18.12.2015 get 3th Wed ==> 16.12.2015 02.11.2015 + (-14) days 19.10.2015 get 3th Wed ==> 21.10.2015 abc(1, 21.10.2015) 21.10.2015 get 3th Wed ==> 21.10.2015 21.10.2015 + (1) month 21.11.2015 get 3th Wed ==> 18.11.2015 abc date: 21.10.2015 (the 3th Wed of previous month) 

Je ne crois pas qu'il n'y ait pas de meilleur moyen de le calculer.