J'ai une prédiction avant de le faire, mais je pense qu'il est important de la garder en forme.
Le streaming en langage Java est une fonctionnalité qui, lorsqu'elle est utilisée correctement, a le potentiel de passer à un code plus lisible, c'est-à-dire de prédire le comportement. Ce serait bien de pouvoir décrire dans un flux peu susceptible de provoquer des branchements.
Cependant, quand vous y pensez au moment de l'exécution, est-ce vraiment bon d'être un flux? Une pratique courante consiste à diffuser ce que vous écrivez en boucle.
Alors, mesurons le temps nécessaire au processus de ** génération de nombres aléatoires 1 million de fois et de les ajouter tous **. L'environnement d'exécution est Win10Pro (i5, 8 Go de RAM).
InfinitTest2_loop.java
public class InfinitTest2_loop {
public static void main(String[] args) {
Double result = 0.0;
var start = System.currentTimeMillis();
for (int i = 0; i < 100 * 10000; i++) {
result += Math.random();
}
var end = System.currentTimeMillis();
System.out.println(result);
System.out.println("Temps requis(milliseconde): " + (end - start));
}
}
Convertissons rapidement ce code en flux. Passons-le à reduction ()
et décrivons le processus d'ajout.
InfinitTest2.java
import java.util.stream.Stream;
public class InfinitTest2 {
public static void main(String[] args) {
var start = System.currentTimeMillis();
Double result = Stream.generate(Math::random)
.limit(100 * 10000)
.reduce((p, q) -> p + q).get();
var end = System.currentTimeMillis();
System.out.println(result);
System.out.println("Temps requis(milliseconde): " + (end - start));
}
}
Alors j'ai essayé les deux. Millisecondes lorsque chacun est exécuté 3 fois
--Version boucle: 45,41,39 --Version Stream: 63,71,70
La version en boucle s'exécute dans environ 70% du temps de traitement de la version de flux. Ouais, la version en boucle est plus rapide car elle ne gère pas mal la classe.
Je ne pense pas que nous devrions nous arrêter ici, Java est Java, y compris l'environnement d'exécution. Par exemple, si vous mettez la VM Java en mode serveur, vous essaierez d'optimiser autant que possible avant de l'exécuter, tout en étant conscient de l'optimisation lors de l'exécution dans une VM normale (Client VM).
PS> java -server -cp . InfinitTest
499714.1320036936
Temps requis(milliseconde): 63
Cela ne change pas beaucoup, mais quand il est répété, il est réglé en moins de 65 millisecondes, il semble donc que vous essayez «d'optimiser dans la mesure du possible».
En matière d'optimisation, le problème de «l'optimisation lors de l'exécution» qui s'est posé rapidement est le mouvement «d'optimisation des pièces souvent exécutées en séquence». En d'autres termes, si elle boucle, cette partie n'est-elle pas accélérée par l'optimisation?
Bouclons une grande partie du processus précédent. J'écrirai ces deux parties en utilisant «for» pour qu'il n'y ait aucune différence.
public class InfinitTest2_loop {
public static void main(String[] args) {
for (int n = 0; n < 100; n++) {
Double result = 0.0;
var start = System.currentTimeMillis();
for (int i = 0; i < 100 * 10000; i++) {
result += Math.random();
}
var end = System.currentTimeMillis();
System.out.println(result);
System.out.println("Temps requis(milliseconde): " + (end - start));
}
}
}
import java.util.stream.Stream;
public class InfinitTest {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
var start = System.currentTimeMillis();
Double result = Stream.generate(Math::random).limit(100 * 10000).reduce((p, q) -> p + q).get();
var end = System.currentTimeMillis();
System.out.println(result);
System.out.println("Temps requis(milliseconde): " + (end - start));
}
}
}
J'ai essayé de le répéter 100 fois. La sortie en millisecondes a progressivement diminué, probablement parce que l'optimisation a commencé en cours.
Quand j'ai éteint chacune des trois dernières fois, c'est devenu comme ça.
--Version boucle: 33,34,22 --Version de flux: 32,30,39
Oh, la différence est assez proche (bien que la version en boucle soit toujours rapide).
Donc, si vous devez remplacer le traitement en boucle par un flux et que vous devez être conscient de la vitesse,
――Sachez que vous pouvez vous attendre à une optimisation par traitement itératif pour accélérer la partie flux.
Est-ce un endroit comme ça?
Je me demande s'il existe un générateur de flux qui génère des données un nombre infini de fois (jusqu'à ce qu'il sorte dans certaines conditions) sans rien passer.
Il s'agit de savoir si while (true) {...}
peut être exprimé dans un flux.