Zrobiłem testa i rzeczywiście wychodzi na to, że czytanie zasobów ze spakowanego JARa jest znacznie wolniejsze.
Jako plik testowy posłużył mi English text z http://www.maximumcompression.com/data/files/index.html
Kod testowy:
package fgd;
import java.io.IOException;
import java.io.InputStream;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
byte[] buffer = new byte[4096];
for (int i = 0; i < 10; i++) {
long startIterationTime = System.currentTimeMillis();
InputStream stream = App.class.getResourceAsStream("/world95.txt");
while (stream.read(buffer) >= 0) ;
long totalIterationTime = System.currentTimeMillis() - startIterationTime;
System.out.println("time taken for iteration: " + totalIterationTime + "ms");
}
long totalTime = System.currentTimeMillis() - startTime;
System.out.println("time taken: " + totalTime + "ms");
}
}
Odpalony wprost z IntelliJa daje taki wynik:
time taken for iteration: 8ms
time taken for iteration: 2ms
time taken for iteration: 1ms
time taken for iteration: 1ms
time taken for iteration: 1ms
time taken for iteration: 0ms
time taken for iteration: 1ms
time taken for iteration: 5ms
time taken for iteration: 1ms
time taken for iteration: 1ms
time taken: 22ms
Odpalony JAR z linii komend daje taki wynik:
time taken for iteration: 13ms
time taken for iteration: 11ms
time taken for iteration: 11ms
time taken for iteration: 10ms
time taken for iteration: 11ms
time taken for iteration: 10ms
time taken for iteration: 11ms
time taken for iteration: 11ms
time taken for iteration: 10ms
time taken for iteration: 11ms
time taken: 109ms
Spróbowałem jeszcze wyłączyć kompresję JARa za pomocą porad tutaj: https://stackoverflow.com/questions/1032685/how-to-turn-off-jar-compression-in-maven
Wyniki:
time taken for iteration: 3ms
time taken for iteration: 1ms
time taken for iteration: 1ms
time taken for iteration: 0ms
time taken for iteration: 1ms
time taken for iteration: 1ms
time taken for iteration: 0ms
time taken for iteration: 1ms
time taken for iteration: 0ms
time taken for iteration: 1ms
time taken: 9ms
Podsumowując:
- najszybciej z nieskompresowanego JARa: 9ms
- nieco wolniej prosto z dysku: 22ms
- bardzo wolno ze skompresowanego JARa: 109ms
Rozwiązaniem na krótką metę jest więc wyłączenie kompresji JARa. Możesz go skompresować po zbudowaniu, np wrzucając go wprost do pliku ZIP, RAR, 7z czy cokolowiek.
Rozwiązaniem na dłuższą metę byłoby poprawne zarządzanie zasobami, a nie wczytywanie ich w kółko. Prawdopodobnie nie dość że w kółko wczytujesz strumienie to jeszcze w kółko tworzysz jakieś obiekty Bitmap, Image czy tym podobne. Wstaw sobie licznik do kodu by sprawdzić ile razy w rzeczywistości wczytujesz zasoby i uzmysłowić sobie skalę problemu.