2009-06-24 15 views
7

Sıkıştırma testi amaçları için, ideal olarak metin, ikili ve karışık formatlarda büyük dosyalar oluşturabilmem gerekir."Doğal" içerikli büyük (> 1 gb) metin + ikili dosyaları hızla nasıl oluşturabilirim? (C#)

  • Dosyaların içeriği tamamen rastgele veya düzgün olmamalıdır.
    Tüm sıfırlar içeren ikili bir dosya iyi değil. Tamamen rastgele veriler içeren bir ikili dosya da iyi değil. Metin için, ASCII'nin tamamen rasgele sıraları olan bir dosya iyi değildir - metin dosyaları, doğal dili veya kaynak kodunu (XML, C#, vb.) Simüle eden desenlere ve frekanslara sahip olmalıdır. Sözde gerçek metin.
  • Her bir dosyanın boyutu kritik değildir, ancak dosya grubu için toplamın ~ 8gb olması gerekir.
  • Dosya sayısını yönetilebilir bir düzeyde tutmak istiyorum, diyelim ki o (10).

ikili dosyaları oluşturmak için, ben büyük bir tampon yeni ve böyle bir döngü içinde FileStream.Write ardından System.Random.NextBytes yapın: Yeterince büyük tampon ile

Int64 bytesRemaining = size; 
byte[] buffer = new byte[sz]; 
using (Stream fileStream = new FileStream(Filename, FileMode.Create, FileAccess.Write)) 
{ 
    while (bytesRemaining > 0) 
    { 
     int sizeOfChunkToWrite = (bytesRemaining > buffer.Length) ? buffer.Length : (int)bytesRemaining; 
     if (!zeroes) _rnd.NextBytes(buffer); 
     fileStream.Write(buffer, 0, sizeOfChunkToWrite); 
     bytesRemaining -= sizeOfChunkToWrite; 
    } 
    fileStream.Close(); 
} 

, haydi 512k deyince, bu 2 veya 3 gb üzerindeki dosyalar için bile nispeten hızlıdır. Ama içerik tamamen rastgele, istediğim bu değil.

Metin dosyaları için, çektiğim yaklaşım Lorem Ipsum kullanmak ve bir StreamWriter aracılığıyla bir metin dosyasına tekrar tekrar yaymaktır. İçerik, rastgele olmayan ve tekdüze değildir, ancak doğal olmayan birçok tekrarlanan bloklara sahiptir. Ayrıca, Lorem Ispum bloğu çok küçük olduğu için (< 1k), çok sayıda döngü ve çok uzun bir zaman alır.

Bunların hiçbiri benim için tatmin edici değil.

Quickly create large file on a windows system? yanıtlarını gördüm. Bu yaklaşımlar çok hızlı, ama sanırım dosyayı sadece sıfırları ya da rastgele verilerle dolduruyorum, bunların hiçbiri istediğim şey değil. Gerekirse contig veya fsutil gibi harici bir işlem yürütmekte sorunum yok.

Testler Windows üzerinde çalışır.
Yeni dosyalar oluşturmaktan ziyade, yalnızca dosya sisteminde var olan dosyaları kullanmak daha mantıklı mı? Bunların yeterince büyük olduğunu bilmiyorum.

Tek bir varolan dosyayla başlatmaya ne dersiniz (belki bir metin dosyası için c: \ windows \ Microsoft.NET \ Framework \ v2.0.50727 \ Config \ enterprisesec.config.cch) ve içeriğini birçok kez çoğaltılıyor? Bu, bir metin veya ikili dosya ile çalışır.

Şu an için bu tür bir çalışmaya sahibim, ancak çalışması çok uzun sürüyor.

Bunu başka kim çözdü?

Bir metin dosyası yazmak için StreamWriter'den daha hızlı bir yol var mı?

Öneriler?

EDIT: Daha doğal bir metin üretmek için Markov zincirinin fikrini beğeniyorum. Yine de, hız konusuna karşı koymaya ihtiyaç var.

+0

Ne tür bir ikili veri benzetmeye çalışıyorsunuz (görüntüler)? Çoğu görüntü formatının önceden sıkıştırılmış olduğunu düşündüğümden, görüntülerde –

+0

daha az duruluyor. Veritabanı dosyalarına veya diğer ikili veri akışlarına daha fazla önem verin. – Cheeso

+0

Bu konuda tam kaynak kodu ile herhangi bir nihai çözüm örneği? – Kiquenet

cevap

4

Bu verileri oluşturmak için bir Markov chain işlemi gibi bir şey arıyor olabileceğinizi düşünüyorum. Her ikisi de stokastiktir (rastgele), fakat aynı zamanda yapılandırılmış, yani finite state machine'a göre çalışır. Gerçekten de, Markov zincirleri insan dillerinde yarı gerçekçi görünümlü bir metin oluşturmak için kullanılmıştır. Genel olarak, düzgün bir şekilde analiz etmek için önemsiz şeyler değildir, ancak belirli özellikler sergilemeleri gerçeği sizin için yeterince iyi olmalıdır. (Yine, sayfanın Properties of Markov chains bölümüne bakınız.) Umarım bir tane nasıl tasarlanacağını görmelisiniz, ancak bunu uygulamak aslında oldukça basit bir kavramdır. Muhtemelen en iyi bahisten, genel bir Markov süreci için bir çerçeve oluşturmak ve daha sonra Markov sürecini "eğitmek" için doğal dili veya kaynak kodunu (rastgele verilerinizi taklit etmek istediğinizi) analiz etmek olacaktır. Sonunda, bu sizin ihtiyaçlarınıza göre çok kaliteli veriler vermelidir. Bu muazzam uzunluktaki test verisine ihtiyacınız varsa, çabaya değer.

+0

tamam, araştıracağım. Bu çok ilginç, verilerin 8GB muazzam * eskiden * ancak web trafiği geçmişi mağazalar, emtia çoklu TB disk dizileri, S3 ve benzeri bugünlerde, 8GB artık gerçekten çok büyük değildir. – Cheeso

+0

Evet, bu muhtemelen doğrudur. Yine de, hesaplama ve I/O zamanı açısından, bugün bile önemli. – Noldorin

+0

Doğru. Markov Zincirleri - Yeni bir uygulama yazmak istediğimi sanmıyorum. Bulduğum, http://blog.figmentengine.com/2008/10/markov-chain-code.html, çok iyi çıktı verdi, ama * çok * yavaştı. – Cheeso

10

Kendinize küçük bir web tarayıcısı kodlayabilirsiniz ...

GÜNCELLEME adamlar Sakin, bu eğer o zaten "çok uzun sürüyor" diye bir çözüm olduğunu söyledi olmasaydı, iyi bir cevap olacaktır.

hızlıca kontrol here şey 8GB indirirken nispeten uzun zaman alacağını gösteriyordu.

+0

Bu şekilde muhtemelen en "doğal" verileri elde edersiniz. –

+0

Ve görüntüleri de indirebilirsiniz. – Benjol

+0

+1. Bu benim ilk düşüncemdi, ancak bu yaklaşımın 'hızlı' kategoriye girdiğinden şüphe duyuyorum. – Kirschstein

14

Metin için, stack overflow community dump kullanabilirsiniz, orada verilerin 300megs yoktur. Yazdığım uygulama ile bir db'ye yüklenmek için yaklaşık 6 dakika sürecek ve muhtemelen tüm yayınları metin dosyalarına dökebilmeniz, 200 K - 1 Milyon metin dosyaları arasında kolayca yaklaşmanızı sağlayacak. (Kaynağa ve xml'ye sahip olma eklenmiş bonus ile). Ayrıca wikipedia dump gibi bir şey kullanabilirsiniz

, çalışmayı kolay süper yapar MySQL formatında gemi gibi görünüyor. Eğer ikili amaçlarla, bölebilmeniz büyük bir dosyada arıyorsanız

, bir VM VMDK kullanabilir ya da DVD lokal yırtık.

Düzenleme

Mark bu da download via bittorrent için kullanılabilir metin (ve ses) için gerçekten iyi bir kaynaktır, proje Gutenberg indir bahseder. metni için

+3

Ben de Gutenberg projesine bakarak bahsetecektim. Düz metin dosyalarının çoğu zaten sıkıştırılmış, bu yüzden hızlı bir indirme olacaktır. http://www.gutenberg.org/catalog/ –

+0

@Mark, iyi nokta, Bir link ekleyeceğim, teşekkürler! –

+0

Vikipedi dökümü bir kısmını kullanan bir sıkıştırma kriter vardır alread edilir: Ipsum rastgele tek kelime seçerek http://cs.fit.edu/~mmahoney/compression/textdata.html – CesarB

1

Eğer bazı başarılar bir english word list alarak ve basit rastgele ondan kelimeleri çekerek olabilir dosyaları. Bu gerçek ingilizce metin üretmeyecek ama ingilizce olarak bulabileceğinize benzer bir harf sıklığı üreteceğini tahmin ediyorum.

daha yapısal bir yaklaşım için bir Markov chain bazı büyük ücretsiz ingilizce metin üzerinde eğitilmiş kullanabilirsiniz.

+0

Ben bu yaklaşımı aldı ama Bu şekilde büyük metin dosyaları oluşturmak için excrutiatingly yavaştı. Markov zinciri yaklaşımı, metnin katı "doğallığına" doğru eğilmiş gibi görünüyor, ki benim için üretim hızından daha az önemli. – Cheeso

+0

Markov zincirleri kesinlikle bunun için doğru yoldur. Hem yüksek kaliteli çıktılar üretecek hem de çok çabuk * çok * üretecekler. – Noldorin

1

Neden Lorem Ipsum'u alıp çıkmadan önce bellekte uzun bir dize oluşturmuyorsunuz. Her seferinde sahip olduğunuz metin miktarını iki katına çıkarırsanız, metin O (log n) oranında genişlemelidir. Verilerin toplam uzunluğunu elden önce hesaplayabilir, böylece içeriği yeni bir dizgeye/diziye kopyalamak zorunda kalmanıza gerek kalmaz.

Arabelleğiniz yalnızca 512k olduğundan veya bu değeri ayarladığınızdan beri, yazmadan önce yalnızca bu kadar çok veri oluşturmanız gerekir, çünkü bu yalnızca dosyaya bir defada gönderebileceğiniz miktardır. Aynı metni tekrar tekrar yazacaksınız, bu yüzden ilk kez oluşturduğunuz orijinal 512K'yı kullanın.

3

Windows dizininin muhtemelen ihtiyaçlarınız için yeterince iyi bir kaynak olacağını düşünüyorum. Eğer metnin peşindeyseniz, .txt dosyalarını arayan dizinlerin her birini tekrarlardım ve bunları doğru boyutta dosya almak için gereken sayıda çıktı dosyasına kopyalarlar.

Ardından, ikili dosyalar için .exes veya .dlls dosyasını arayarak benzer bir yaklaşım kullanabilirsiniz.

1

Vikipedi, karışık metin ve ikili için sıkıştırma testi için mükemmeldir. Karşılaştırma karşılaştırmaları gerekiyorsa, Hutter Prize site, Wikipedia'nın ilk 100mb'si için yüksek bir su işareti sağlayabilir. Mevcut kayıt 6.26 oran, 16 mb.

0

Tüm hızlı girişler için teşekkürler. Hız ve "doğallık" problemlerini ayrı ayrı ele almaya karar verdim. Doğal-ish metninin üretimi için birkaç fikir bir araya getirdim.

  • Metin oluşturmak için, Mark Rushakoff tarafından önerilen şekilde project gutenberg kataloğundan birkaç metin dosyasıyla başlıyorum.
  • Bu alt kümenin bir belgesini rastgele seçip indiriyorum.
  • Daha sonra indirilen metni giriş olarak kullanarak bir Markov İşlemini suggested by Noldorin olarak uygularım.
  • Örnek olarak Pike's economical Perl implementation kullanarak C# 'da yeni bir Markov Zinciri yazdım. Her seferinde bir sözcük bir metin oluşturur.
  • Verimlilik için, bir seferde tek bir kelime 1gb metin üretmek için saf Markov Zinciri kullanmak yerine, kod ~ 1mb rastgele bir metin oluşturur ve daha sonra tekrar tekrar rastgele parçaları alır ve bunları birlikte globs.

GÜNCELLEME: İkinci sorununa gelince, hız - Ben mümkün olduğunca IO ortadan kaldırmak için bir yaklaşım aldı, bu 5400rpm mini mil ile benim zavallı dizüstü yapılıyor. Bu, sorunu tamamen yeniden tanımlamamı sağladı - rastgele içerikle bir DOSYA oluşturmak yerine, gerçekten istediğim şey rastgele içerik. Bir Markov Zinciri etrafına sarılmış bir Akışı kullanarak, bellekte metin oluşturabilir ve 8g yazma ve 8g okumayı kaldırarak kompresöre aktarabilirim. Bu özel test için sıkıştırma/dekompresyon gidiş gelişini doğrulamam gerekiyor, bu yüzden orijinal içeriği korumam gerekmiyor. Böylece akış yaklaşımı, işleri hızlandırmak için iyi çalıştı. Gerekli sürenin% 80'ini kesti.

Henüz ikili neslin nasıl yapılacağını henüz çözemedim, ancak muhtemelen benzer bir şey olacaktır.

Tüm yardımcı fikirler için tekrar teşekkür ederiz.

İlgili konular