I have a prediction before I do it, but I think it's important to keep it in shape.
Streams in the Java language are a feature that allows you to write in line with the flow, and if used properly, can move you to more readable code, that is, to predict behavior. It would be nice to be able to describe in a flow that is unlikely to cause branching.
However, when you think about the runtime, is it really good to be a stream? A common practice is to stream what you were writing in a loop.
So, let's measure the time required for the process of ** generating random numbers 1 million times and adding them all **. The execution environment is Win10Pro (i5, 8GB 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("Time required(millisecond): " + (end - start));
}
}
Let's quickly convert this code to a stream. Let's pass it to reduce ()
and describe up to the addition process.
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("Time required(millisecond): " + (end - start));
}
}
So I tried both. Milliseconds when each is executed 3 times
--Loop version: 45,41,39 --Stream version: 63,71,70
The loop version runs in about 70% of the processing time of the stream version. Yeah, the loop version is faster because it doesn't handle the class poorly.
I don't think we should end here, Java is Java including the execution environment. For example, if you put the Java VM in server mode, you will try to optimize as much as possible before executing, instead of being aware of the optimization during execution in a normal VM (Client VM).
PS> java -server -cp . InfinitTest
499714.1320036936
Time required(millisecond): 63
That? It doesn't change much, but when it's repeated, it's within 65 milliseconds, so it seems that you're trying to "optimize to the extent possible."
When it comes to optimization, the problem of "optimization during execution" that came up quickly is the movement to "optimize the parts that are often executed in sequence." In other words, if it loops, isn't that part speeded up by optimization?
Let's loop a lot of the previous process. I will write both of these parts using for
so that there is no difference.
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("Time required(millisecond): " + (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("Time required(millisecond): " + (end - start));
}
}
}
I tried to repeat it 100 times. The millisecond output gradually decreased, probably because optimization started on the way.
When I put out each of the last three times, it became like this.
--Loop version: 33,34,22 --Stream version: 32,30,39
Oh, the difference is pretty close (although the loop version is still fast).
So, if you should replace loop processing with a stream and you have to be aware of speed,
--Be aware that the speedup of the stream part can be expected to be optimized by iterative processing. --If the loop is processed only once, it is faster to stay in the loop without expecting optimization.
Is it a place like that?
I wonder if there is a stream generator that generates infinite number of data (until it breaks out under some conditions) without passing anything.
It is a story about whether while (true) {...}
can be expressed as a stream.
Recommended Posts