Soru (şimdi) int, bir Harita gibi ilkel türler kullanılarak temsil edilebilecek çok sayıda veri depolamakla ilgilidir . Buradaki cevapların bazıları bence çok yanıltıcı. Bakalım neden.
Hem çalışma zamanını hem de bellek tüketimini ölçmek için ölçütü trove'dan değiştirdim . İlkel tipler için başka bir koleksiyon kütüphanesi olan bu karşılaştırmaya PCJ ekledim (bunu yoğun olarak kullanıyorum). 'Resmi' trove kıyaslaması IntIntMaps'i Java Collection'larla karşılaştırmaz Map<Integer, Integer>, muhtemelen depolama Integersve depolama intsteknik açıdan aynı değildir. Ancak bir kullanıcı bu teknik ayrıntıyı önemsemeyebilir, intsverimli bir şekilde temsil edilebilen verileri saklamak ister .
Önce kodun ilgili kısmı:
new Operation() {
private long usedMem() {
System.gc();
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
// trove
public void ours() {
long mem = usedMem();
TIntIntHashMap ours = new TIntIntHashMap(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
ours.put(i, i);
}
mem = usedMem() - mem;
System.err.println("trove " + mem + " bytes");
ours.clear();
}
public void pcj() {
long mem = usedMem();
IntKeyIntMap map = new IntKeyIntOpenHashMap(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
map.put(i, i);
}
mem = usedMem() - mem;
System.err.println("pcj " + mem + " bytes");
map.clear();
}
// java collections
public void theirs() {
long mem = usedMem();
Map<Integer, Integer> map = new HashMap<Integer, Integer>(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
map.put(i, i);
}
mem = usedMem() - mem;
System.err.println("java " + mem + " bytes");
map.clear();
}
Verilerin ilkel olduğunu düşünüyorum ints , aklı başında gibi görünüyor. Ancak bu, ilkel koleksiyon çerçeveleri için gerekli olmayan otomatik boks nedeniyle java util için bir çalışma zamanı cezası anlamına gelir.
gc()WinXP, jdk1.6.0_10'da çalışma zamanı sonuçları ( elbette çağrılar olmadan ):
100000 koyma işlemleri 100000 işlemler içerir
java koleksiyonları 1938 ms 203 ms
bölme 234 ms 125 ms
pcj 516 ms 94 ms
Bu zaten ciddi gibi görünse de, böyle bir çerçeveyi kullanmanın nedeni bu değildir.
Nedeni bellek performansıdır. 100000 içeren bir Harita için sonuçlarint giriş :
java koleksiyonları 6644536 ve 7168840 bayt arasında dalgalanır
trove 1853296 bayt
pcj 1866112 bayt
Java Collections , ilkel koleksiyon çerçevelerine kıyasla belleğin üç katından fazlasına ihtiyaç duyar . Yani, çalışma zamanı performansını büyüklüklerle azaltan disk IO'ya başvurmadan bellekte üç kat daha fazla veri tutabilirsiniz. Ve bu önemli. Nedenini bulmak için yüksek ölçeklenebilirliği okuyun .
Deneyimlerime göre, yüksek bellek tüketimi Java ile ilgili en büyük performans sorunudur, bu da elbette daha kötü çalışma zamanı performansı ile sonuçlanır. İlkel koleksiyon çerçeveleri gerçekten yardımcı olabilir.
Yani: Hayır, java.util cevap değil. Ve Java koleksiyonlarına "işlevsellik katmak" verimlilik sorulduğunda önemli değildir. Ayrıca, modern JDK koleksiyonları yapmak değil "bile uzman Olimpiyatı koleksiyonları gerçekleştirmek dışı".
Feragatname: Buradaki kıyaslama tam olmaktan uzak değildir ve mükemmel değildir. Bu, birçok projede yaşadığım noktayı eve götürmek içindir. İlkel koleksiyonları balık API tolere kullanışlı yeterli - eğer sen birçok bilgiye sahip olan çalışırlar.