2012-11-11 26 views
5

Büyük CSV formatlı dosyaları (genellikle 200-600mb) verimli bir şekilde Java (daha az bellek ve mümkün olan en hızlı erişim) ile yüklemeye çalışıyorum. Şu anda, program Dize Dizileri Listesi kullanıyor. Bu işlem daha önce her bir CSV satırı için bir tablo ve her bir "satır" tablosunu tutan bir tablo kullanılarak bir Lua programıyla işlenmiştir. Aşağıda Java - büyük miktarda String dizisini verimli bir şekilde depolamak

bellek farklılıklar ve yükleme süreleri bir örnektir:

  • CSV Dosya - 232mb
  • Lua - bellekte 1,378mb - - 157 saniye
  • Java yüklemek için - bellekte 549mb 12 yüklenecek saniye

Doğru hatırlıyorsam, bir Lua tablosundaki öğeleri çoğaltmak, gerçek değere referans olarak bulunur. Java örneğinden şüpheleniyorum, Liste her bir yinelenen değerin ayrı kopyalarını tutuyor ve daha büyük bellek kullanımıyla ilgili olabilir. Aşağıda

CSV dosyaları elde edilen verilerle ilgili bazı arka plan: Her satır içinde
  • Belli alanlar Strings (Örn alanında bir dizi birini içerebilir Her alan bir dize oluşur

    • 3 olabilir "kırmızı", "yeşil" veya "mavi").
    • İçerik içinde çoğaltması olan çoğaltması var. Aşağıda

  • yüklenen verilerin gerekebilir bazı örnekler şunlardır: Belirli bir dize ile eşleşen ve bir GUI eşleşen dizeleri
  • Ekran eşleşmeleri dönmeye çalışan tüm Strings aracılığıyla

    • Arama tablo (alanlara göre sıralama).
    • Dizeleri değiştirin veya değiştirin.

    Soruma Soru: Verileri tutmak için daha az bellek gerektiren, ancak yine de verileri kolay ve hızlı bir şekilde arama/sıralama yapabilecek özellikler sunan bir koleksiyon var mı?

  • +1

    yalnızca birkaç olası değerleri tutan, yapabilirsin [stajyer onları] (http://docs.oracle bellek kullanımını azaltmak için./javase/7/docs/api/java/lang/String.html # intern% 28% 29). Ayrıca bakınız: http://stackoverflow.com/a/1855195/829571 – assylias

    +0

    Teşekkürler assylias Bunu kullanarak bazı testler yapacağım. Kısa Strings için etkili olup olmadığını biliyor musunuz - E.g. "To" veya "Go". Alanların çoğu 45 karakter + olan dizeleri içerir, ancak bazıları oldukça kısadır (4 veya daha az). – user1816198

    +2

    http://stackoverflow.com/questions/12792942/alternatives-to-java-string-interning adresine bakın –

    cevap

    0

    Belki bu makalede bazı yardımcı olabilir: sadece bir yan not olarak

    http://www.javamex.com/tutorials/memory/string_saving_memory.shtml

    +0

    Teşekkürler - çok yararlı bilgiler. – user1816198

    +1

    Her iki makaleyi de makaleyle sunmaya çalıştım. Stajyer() en fazla hafızayı kaydeder. Denemeye devam edeceğim (özellikle de projemden daha fazlasını bitirdikten sonra), ancak bu kesinlikle bellek kullanımımı çok daha hızlı yükleme süreleriyle Lua'ya göre koyar. – user1816198

    +0

    Bu yüzden sadece bağlantıya cevap vermemelisiniz - bağlantı artık öldü. –

    0

    Bellek sorununuzu en iyi duruma getirmek için, özellikle çok fazla kopyası olan alanlar için Flyweight modelini kullanmanızı öneriyorum.

    Koleksiyon olarak bir TreeSet veya TreeMap kullanabilirsiniz. Eğer LineItem sınıfa iyi bir uygulama verirsen

    bellek çok kullanmak optimize edebilirsiniz (equals, hashcode ve Comparable uygulamak).

    0

    DAWG

    bir asiklik kelime grafik kelime saklamak için en etkili yolu (bellek tüketimi için en iyi durumda) olan yöneliktir.

    Fakat muhtemelen burada aşırı miktarda olmadığından, diğerleri çoğaltmaları oluşturmadığı için aynı örneğe birden çok başvuruda bulunun.

    +0

    Teşekkürler Bu seçeneğe biraz daha bakacağım. Henüz aşırı bir şey düşünmüyordum - daha verimli bu oturum başına daha fazla veri yüklenebilir ve bu son kullanıcı için daha iyi. – user1816198

    0

    .

    Yinelenen dize verileri için şüphe duymanıza gerek yok, çünkü java'nın kendisi de tüm dizeler kesin ve tüm referanslar aynı nesneyi bellekte hedefliyor.

    lua işi yapar, ancak java o

    +0

    Eğer bu eşittirden daha doğruysa ve == – Igor

    +0

    karşılaştırması için iş yapacaksa, eşittir, javadaki nesneleri karşılaştırmanız gerektiği gibi eşittir, == da çalışırdı, ama sadece tür JVM dahili yol dizeleri nedeniyle, –

    +0

    dizeleri, ne kadar bellek java vm dahili dize referansları tutmak için tutar emin değilim, ama yeterince büyük bir programda çalıştığından emin değilim == çalışmaz – Igor

    1

    biri kolay çözüm ayrıca oldukça verimli nasıl olması gerektiğini çok emin değilim. Tüm benzersiz dizelere referanslar koyabileceğiniz için HashMap'a sahip olabilirsiniz. Ve ArrayList içinde, HashMap'daki mevcut benzersiz dizelere başvurmanız yeterlidir.

    şey gibi:

    private HashMap<String, String> hashMap = new HashMap<String, String>(); 
    
    public String getUniqueString(String ns) { 
        String oldValue = hashMap.get(ns); 
        if (oldValue != null) { //I suppose there will be no null strings inside csv 
        return oldValue; 
        }   
        hashMap.put(ns, ns); 
        return ns; 
    } 
    

    Basit kullanımı: Eğer bu sütunu 3 biliyorsanız

    List<String> s = Arrays.asList("Pera", "Zdera", "Pera", "Kobac", "Pera", "Zdera", "rus"); 
    List<String> finS = new ArrayList<String>(); 
    for (String er : s) { 
        String ns = a.getUniqueString(er); 
        finS.add(ns); 
    } 
    
    +0

    ses zaten java tarafından optimize edilmiş şeyleri optimize etmeye çalışıyormuş gibi (bellekte çift taraflı dizeler için bellek tasarrufu), böyle bir uygulamaya gerek yok, cevabımı gör –

    İlgili konular