2012-04-10 24 views
5

Verileri bellekte oldukça karmaşık ve büyük bir veri yapısına (birkaç GB) hazırlayan ve diske dönüştüren bir Java programına ve bellekteki serileştirilmiş veri yapısını okuyan başka bir programa sahip bir Java programım var. Seri hale getirme adımının oldukça yavaş olduğunu ve CPU'ya bağlı olduğunu fark ettim. (top'da% 100 CPU kullanımı, ancak sadece 3 ila 5 MB/s, iotop ile okunmaktadır, ki bu sabit sürücüde sıralı okumalar için çok düşüktür). CPU oldukça yeni (Core i7-3820), yapı belleğe sığar, swap alanı yapılandırılmamış.Java Deserialization neden CPU'ya bağlı?

Neden böyle? Java'daki nesneleri, darboğaz olarak kullanmayan nesneleri serileştirmenin alternatif bir yolu var mı?

FileInputStream f = new FileInputStream(path); 
ObjectInputStream of = new ObjectInputStream(f); 
Object obj = of.readObject(); 
+1

IIRC. Bu yavaş. Tüm bunlardan kaçınmak için kavramsal olarak kolay ama "yazmanın bir sürü" yolu var - bunu elle yapın. Yani, nesnel olarak, alana göre, ikili bir akışa nesneleri yazınız. Ve yükleme için ters. – harold

+1

Bu yardımcı olabilir: http://vanillajava.blogspot.co.uk/2011/10/serialization-using-bytebuffer-and.html – assylias

+0

'FileInputStream' bir' BufferedInputStream' ile sarmayı deneyebilir misiniz? –

cevap

4

Seri kaldırma oldukça pahalı: Burada

durumunda bu konularda, seri kaldırma kodudur. Eğer jenerik serileştirme kullanırsanız, çok sayıda yansıma ve nesnelerin yaratılmasını kullanır.

Yansıma yerine daha hızlı ve en çok üretilen kod olan çok sayıda alternatif vardır.

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

Sen Externalizable kullanıyor hızlı biri sizin için bir seçenek olabilir ki dikkat edecektir. Bu, nesnelerin serileştirilmesi ve serileştirilmesi için özel yöntemler eklemek anlamına gelir. Ben çok hızlı yaklaşımları ama yazdım

ile bu bakmadan

2

Söylemesi zor (onları serisini gerek kalmadan yani) yerinde dosyasındaki verileri bunları geri dönüşüm veya kullanarak herhangi nesneleri oluştururken bu önlemek Bir profiler veya nesnenizin yapısının gerçek hiyerarşisi hakkında çok şey biliyordum, ama eğer "oldukça karmaşık" ve "birkaç GB" büyüklüğüne göre, muhtemelen binlerce bireysel nesneyle uğraştığını varsayıyorum.

Buradaki en iyi tahminim, performansınızın Java Reflection tarafından öldürülmesidir. Yansıma, nesnelerin doğrudan kod içinde çağrılmasından en az iki büyüklük sırası daha yavaş olduğu bilinen akışınızdan Nesneleri oluşturmak için kullanılır. Eğer nesnenizde tonlarca "küçük" Nesne varsa, Yansıma onları yeniden inşa etmek için çok fazla zaman harcayacak. (Önceden varsa) deneyebilirsin

Bir şey sizin Serializable sınıfların her birinin en üstünde aşağıdaki satırı ilan etmek olacaktır:

private static final long serialVersionUID = [some number]L; 

Bu kimliği beyan etmezseniz, Java bunu hesaplamak zorunda kalacaktır, bu yüzden bildirerek bazı CPU döngülerini kaydedersiniz. Detaylı bilgi için

: nasıl .NET serileştiriciler çalışması ile karşılaştırılabilir sihirli yansıma kullanan

http://oreilly.com/catalog/javarmi/chapter/ch10.html

İlgili konular