Próbowałem zoptymalizować wykorzystanie pamięci RAM w grze na Androida, zmieniając prymitywy int na szorty. Zanim to zrobiłem interesowałem się wydajnością typów pierwotnych w Javie.Dlaczego krótki typ pierwotny jest znacznie wolniejszy od długiego lub int?
Stworzyłem ten mały testowy benchmark używając biblioteki zacisków.
public class BenchmarkTypes extends Benchmark {
@Param("10") private long testLong;
@Param("10") private int testInt;
@Param("10") private short testShort;
@Param("5000") private long resultLong = 5000;
@Param("5000") private int resultInt = 5000;
@Param("5000") private short resultShort = 5000;
@Override
protected void setUp() throws Exception {
Random rand = new Random();
testShort = (short) rand.nextInt(1000);
testInt = (int) testShort;
testLong = (long) testShort;
}
public long timeLong(int reps){
for(int i = 0; i < reps; i++){
resultLong += testLong;
resultLong -= testLong;
}
return resultLong;
}
public int timeInt(int reps){
for(int i = 0; i < reps; i++){
resultInt += testInt;
resultInt -= testInt;
}
return resultInt;
}
public short timeShort(int reps){
for(int i = 0; i < reps; i++){
resultShort += testShort;
resultShort -= testShort;
}
return resultShort;
}
}
Wyniki testu zaskoczyły mnie.
okoliczności testowe
Benchmark uruchomić w bibliotece zacisku. Wynika
test
https://microbenchmarks.appspot.com/runs/0c9bd212-feeb-4f8f-896c-e027b85dfe3b
Int 2.365 ns
Długie 2.436 ns
Krótki 8.156 ns
test konkluzja?
Krótki typ pierwotny jest znacznie wolniejszy (3-4 ~ razy) niż typ pierwotny long i int pierwotny?
Pytanie
Dlaczego jest krótki prymitywny znacznie wolniej niż int lub długo? Spodziewam się, że typ pierwotny int będzie najszybszy na 32-bitowej maszynie wirtualnej, a długi i krótki będzie równy w czasie lub krótki, aby być jeszcze szybszy.
Czy dotyczy to również telefonów z systemem Android? Wiedząc, że telefony z systemem Android działają na ogół w środowisku 32-bitowym, a teraz w dzień coraz więcej telefonów zaczyna być dostarczanych z procesorami 64-bitowymi.
Nie rozgrzałeś JIT. Nie wykonałeś wystarczającej liczby iteracji. To nie jest tak, jak mikrobisz Javę. –
Jest (najprawdopodobniej) spowodowany przez konwersję Java krótki (za każdym razem) na int (lub długi) dla operacji arytmetycznych –
@GermannArlington - Nie. Prawdziwym wyjaśnieniem różnicy czasów 1000x jest to, że benchmark jest niepoprawnie zapisany. Zobacz powiązane pytania i odpowiedzi. –