Java HashMap performans optimizasyonu / alternatif | Netgez.com
SORU
18 Kasım 2009, ÇARŞAMBA


Java HashMap performans optimizasyonu / alternatif

Büyük bir HashMap oluşturmak istiyorum ama put() performans yeterince iyi değil. Herhangi bir fikir?

Diğer veri yapısı önerilerinizi bekliyoruz ama Java Haritası arama özelliği istiyorum:

map.get(key)

Benim durumumda 26 milyon site ile bir harita oluşturmak istiyorum. Standart Java HashMap koymak hızını kullanarak olur dayanılmaz 2-3 milyon eklemeler sonra yavaş.

Ayrıca, eğer anahtarlar için farklı hash kod dağıtımları kullanarak yardımcı olabilir biliyor mu?

Hashcode benim yöntem:

byte[] a = new byte[2];
byte[] b = new byte[3];
...

public int hashCode() {
    int hash = 503;
    hash = hash * 5381   (a[0]   a[1]);
    hash = hash * 5381   (b[0]   b[1]   b[2]);
    return hash;
}

Ayrıca birleştirici özelliği eşit nesneler aynı hashcode sağlamak için kullanıyorum. Diziler aralığında değerler ile bayt 0 - 51. Değerler sadece bir kez ya da bir dizi kullanılır. Nesneleri bir dizi aynı değerleri içeriyorsa eşittir (ya da sırada) ve aynı b dizisi için de geçerli. {0,1} b = {45,12,33} ve {1,0} a = b = {33,45,12} eşittir.

DÜZENLEME, bazı notlar:

  • Bir kaç kiÅŸi karma harita veya diÄŸer veri yapısı 26 milyon girdileri saklamak için kullanarak eleÅŸtirdi. Ben bu garip görünüyor neden göremiyorum. Bana klasik veri yapıları ve algoritmalar bir sorun gibi görünüyor. 26 milyon parça var ve hızlı bir ÅŸekilde onları içine yerleÅŸtirin ve onları bir veri yapısı aramak için güçlü olmak istiyorum: benim veri yapısı ve algoritmalar ver.

  • Varsayılan baÅŸlangıç kapasitesi ayarı HashMap için 26 milyon Javaazaltırperformans.

  • Bazı insanlar veritabanları, kesinlikle akıllı bir seçenek olduÄŸu baÅŸka durumlarda kullanmayı önerdi. Ama ben gerçekten soran bir veri yapıları ve algoritmalar soru, tam bir veritabanı olurdu abartılı ve çok daha yavaÅŸ daha iyi bir çözüm datastructure (sonra tüm veritabanını sadece yazılım ama olurdu haberleÅŸme ve muhtemelen hard disk gereklidir).

CEVAP
19 Kasım 2009, PERŞEMBE


Birçok kişi hashCode() yöntem suçlu olduğunu belirttim. Sadece 26 milyon farklı nesneler için yaklaşık 20.000 kodları üretiyor. Karma kova başına 1,300 nesneleri ortalama = çok ama çok kötü. Ancak eğer temel 52 sayı iki diziler çevirirsem her nesne için benzersiz bir hash kodu almak için garanti ediyorum:

public int hashCode() {       
    // assume that both a and b are sorted       
    return a[0]   powerOf52(a[1], 1)   powerOf52(b[0], 2)   powerOf52(b[1], 3)   powerOf52(b[2], 4);
}

public static int powerOf52(byte b, int power) {
    int result = b;
    for (int i = 0; i < power; i  ) {
        result *= 52;
    }
    return result;
}

Diziler yöntemleri eşit nesneler aynı karma kodu var hashCode() sözleşme yerine bunu sağlamak için sıralanır. 2,000,000 100,000 koyar, 100,000 ikinci bina ötede başına koyar sayısı ortalaması olduğu için eski yöntemi kullanarak:

168350.17
109409.195
81344.91
64319.023
53780.79
45931.258
39680.29
34972.676
31354.514
28343.062
25562.371
23850.695
22299.22
20998.006
19797.799
18702.951
17702.434
16832.182
16084.52
15353.083

Yeni yöntemi kullanarak verir:

337837.84
337268.12
337078.66
336983.97
313873.2
317460.3
317748.5
320000.0
309704.06
310752.03
312944.5
265780.75
275540.5
264350.44
273522.97
270910.94
279008.7
276285.5
283455.16
289603.25

Çok çok daha iyi. Eski yöntem yeni bir iyi bir işlem hacmi devam ederken çok hızlı bir şekilde kuyruklu kapalı.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EminemMusic

    EminemMusic

    9 ÅžUBAT 2007
  • Rozetked | Обзоры

    Rozetked | Ð

    5 AÄžUSTOS 2011
  • TitaniumBackup

    TitaniumBack

    10 EYLÜL 2011