Answer the question
In order to leave comments, you need to log in
How does an application run faster in a loop in Java?
Hello, I've got this dilemma.
For example, I have a User object, and I need to iterate over the data from the array and initialize the User. Will there be profit from moving the user variable outside the block with a cycle or not?
That is, it will be faster like this:
User user = null;
for (int i=0;i<userListData.size();i++, user = new User(userListData.get(i))){
user.sendToHome();
}
for (int i=0;i<userListData.size();i++){
User user = new User(userListData.get(i));
user.sendToHome();
}
Answer the question
In order to leave comments, you need to log in
In both cases, the user variable will be declared once, and an object of type User will be created and assigned to this variable as many times as there are loop iterations. So there will be no gain in terms of speed, but the second option is stylistically correct .
If you really want measurements, you can throw benchmarks on JMH :
package com.example;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
class User {
private final String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class MyBenchmark {
// Загрузка списка имён для инициализации объектов
@State(Scope.Thread)
public static class MyState {
public List<String> nameList;
@Setup(Level.Trial)
public void setup() throws IOException {
nameList = new ArrayList<>();
ClassLoader classLoader = getClass().getClassLoader();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
classLoader.getResourceAsStream("names.txt")))) {
String line;
while ((line = br.readLine()) != null) {
nameList.add(line.trim());
}
}
}
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void outerVarDef(MyState state, Blackhole blackhole) {
long counter = 0;
// Если здесь оставить null, как у вас написано,
// то получим NullPointerException на первой итерации
User user = new User(state.nameList.get(0));
// Конструкцию i++, user = new User(userListData.get(i)) можно и нужно сократить
// так и короче, и красивее, и OutOfBoundException не получим
for (int i = 0; i < state.nameList.size(); user = new User(state.nameList.get(i++))) {
counter += user.getName().length(); // Чтобы избежать Dead Code Elimination
}
blackhole.consume(counter);
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void innerVarDef(MyState state, Blackhole blackhole) {
long counter = 0;
for (int i = 0; i < state.nameList.size(); i++) {
User user = new User(state.nameList.get(i));
counter += user.getName().length(); // Чтобы избежать Dead Code Elimination
}
blackhole.consume(counter);
}
}
To be sure, try it yourself and find the fastest option like this:
long start = System.currentTimeMillis();
//цикл
long result = System.currentTimeMillis() - start;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question