Rapidement carré un double
Je suis à la recherche de la façon la plus rapide à la place d'un lit double (double d
). Jusqu'à présent, je suis venu avec deux approches:
1. d*d
2. Math.pow(d, 2)
Pour tester la performance, j'ai mis en place trois cas de test, dans chacun, j'générer des nombres aléatoires à l'aide de la même graine pour les trois cas et il suffit de calculer le carré du nombre dans une boucle de 100 000 000 de fois.
Dans le premier cas de test numéros sont générés à l'aide de random.nextDouble()
dans le second cas, à l'aide de random.nextDouble()*Double.MAX_VALUE
et dans le troisième, à l'aide de random.nextDouble()*Double.MIN_VALUE
.
Les résultats d'un couple de pistes (que des résultats approximatifs, il y a toujours des variations, exécuté à l'aide de java 1.8, compilé pour la version 1.6 de java sur Mac OSX Mavericks)
Approach | Case 1 | Case 2 | Case 3
---------•--------•--------•-------
1 | ~2.16s | ~2.16s | ~2.16s
2 | ~9s | ~30s | ~60s
La conclusion semble être que la méthode 1 est plus rapide mais aussi qui Math.pow
semble se comporter de la sorte de bizarre.
J'ai donc deux questions:
1 Pourquoi est Math.pow
si lent, et pourquoi faut-il faire face mal avec > 1
et encore pire avec < -1
numéros?
2 Est-il un moyen d'améliorer les performances sur ce que j'ai suggéré que l'approche 1? Je pensais à quelque chose comme:
long l = Double.doubleToRawLongBits(d);
long sign = (l & (1 << 63));
Double.longBitsToDouble((l<<1)&sign);
Mais c'est un faux, et b) la même vitesse que l'approche 1.
source d'informationauteur Samuel
Vous devez vous connecter pour publier un commentaire.
Le moyen le plus rapide pour calculer le carré d'un nombre est à multiplier par lui-même.
C'est vraiment pas, mais elle est performante l'exponentiation au lieu d'une simple multiplication.
D'abord, parce qu'il ne l'math. À partir de la Javadoc il contient également des tests pour de nombreux cas de coin. Enfin, je ne voudrais pas trop compter sur votre micro-benchmark.
Quadrature par multipling avec l'auto est la manière la plus rapide. Parce que cette approche peut être directement traduit en simple, non ramifiés bytecode (et donc, indirectement, le code machine).
Mathématiques.pow() est une fonction complexe qui est livré avec un certain nombre de garanties pour les cas limites. Et il besoin d'être appelée au lieu d'être insérée.
Math.pow()
est lent, car il a à connaître du cas générique ou élever un nombre à une puissance.Quant à savoir pourquoi il est plus lent avec des nombres négatifs, c'est parce qu'il a pour tester si la puissance est positive ou négative, afin de donner le signe, de sorte qu'il est encore une opération à faire.