1. Tabiki olur 2. Daha az surede yapmak bile mumkun 3. Kesinlikle normal degil |
Rica etsem çok basit bir algoritmayla yardımcı olabilir misiniz? fikir versin yeterli. Geliştirmeyi halledebilirim. |
Oncelikle ise String ve StringBuilder arasindaki farklara bakarak baslayabilirsin. |
Yapılan işlemler bişey değil, sadece dosya kopyalıyorsun. Buffer ı 64kb civarı ayarla ve yapabilirsen yazmayı başka thread e al. Fakat yine de uzun sürer, sanırım 5gb falandır dosya? |
Çok sağolun. Haklısınız. Yaptığım iş temelde bir dosyanın içeiriğinde minik bir değişiklik yaparak kopyalamak. Tahmininiz de doğru. Okumam gereken dosya 5-6 GB civarında. Ben hayatımda böyle bir .txt dosyasıyla hiç başbaşa kalmamıştım. Benim yaptığım .exe nin yazma hızı 10 kb/sn civarında. Bunun 10 MB/sn mertebelerinde olmasını bekliyorlar. Açıkçası müdürümün dediği pek inandırıcı gelmedi. Bukadar büyük metin dosyasının windowsta açılması bile uzun dakikalar sürüyor. Buffer meselesini araştıracağım. Çünkü bugüne kadar hız hiç bukadar ihtiyaç olmamıştı benim için. Çünkü basit excell fonksiyonlarıyla işlem yapılan uygulamalarla uğraşıyoruz. Konuyu açtığımdan beri hala bakınıyorum. Acaba çok basit bir şekilde hızlı okuyup hızlı yazan küçük birşey paylaşabilir misiniz? Başka bişey olmasına gerek yok. Tekniği görebilmek adına. Olursa iyi olur. Olmazsa yukarıda araştırmamın faydalı olacağı söylenilen konuları araştıracağım. |
Yazdığın koda pek dikkat etmemiştim ama 10kb/sn deyince bakma ihtiyacı hissettim. :) C# bilmediğim için detaylı bilgi veremem ama kodda ciddi hatalar gördüm. 1- Dosya okuyup yazan nesnelerin buffer boyunu alan kurucu metodları varmış. Bunları kullan ve buffer ı 64 * 1024 yap.http://msdn.microsoft.com/en-us/library/vstudio/72d9f8d5(v=vs.110).aspx 2- decimal türü 128 bitmiş, oldukça yavaş çalışır. float ya da double kullan. 3- Ölümcül bir hata yapmışsın, yavaşlığın ana kaynağı bu. "yazici" metodun her satırı yazarken yeni nesne kuruyor ve sonra da dosyayı kapatıyor. Dosya kapatılırken bütün buffer dosyaya yazılır (flush) sonra kapatılır. Diğer bir deyişle buffer hiç dolmaz, yani etkisiz hale gelir. Ekstra cpu kullanımı da cabası. Yapman gereken şey streamreader ve streamwriter nesneleri ya sınıfın bir üyesi olacak, ya da static olacak (bu daha iyi). Bu durumda yazici metodun sadece tek satırdan ibaret olur. "yaz.WriteLine(blabla);" Dosya komple yazıldıktan sonra Close ile kapatırsın ve nesneleri null larsın ki çöp toplayıcı işini yapsın. |
Bence nosql konusunu arastir. |
Eyvallah abi.. hemen dediklerini düzeltme çalışmasına başlıyorum. Cevap veren bütün arkadaşlar teşekkür ederim. Sonuca ulaşamazsam yine yazarım.. @elektro_gadget ![]() |
SSIS ile aslında bu işler olur,iki flat file arasına bir derived kolon üzerinden islemlerini tanımla koy msql servera tanımla jobunu babalar gibi isi bitirsin senin mudurde bu ne yaa desin :)) |
İlk önce döngünün içinde her seferinde yeniden dosyayı kapattığım kısmı döngü sonuna aldım. Ayrıca Decimal yerine double kullandım. Sadece bu bile 6 saat sürecek işi 20 dk ya kadar düşürdü. Buffer olayını araştırdım ama programa ekleyemedim. Ve string işlemlerimi hızlandırmak adına stringbuilder üzerinde araştırma yaptım. String builder ile birleştirmeler yaptım ama biyerde hata yapıyor olmalıyım ki sonuç dosyası 60 kat şişiyor. Ve textdosyasını açamıyorum. Yani içeride neler oluyor göremiyorum ![]() Cevaplar için teşekkürler. Yeni fikirlerinize açığım. nonsql baya derin konu gibi geldi. Enazından onun için şimdilik pek vaktim yok. Buffer ve string builder üzerinde yoğunlaşacağım. |
İşlemleri çok daha kısaltma amaçlı çalışmalarım hala devam ediyor. Bütün dosyayı Stringbuilder'a atayıp, stringbuilderı stringe atayıp sonra işlemlere geçersem daha hızlı olacağını düşünüyorum. Fakat dosyayı stringbuildera aktarırken out of memory hatası almaya başladım. Stringbuilderın kapasitesini aşıyor dosya içeriği. Nasıl bir yol izlemeliyim? |
evde 120 milyon satırlı dosya yaptım yaklaşık 6-7 dk da bitiyor private void button1_Click(object sender, EventArgs e) { string[] metin; decimal hn; decimal sn; string yazi; StreamReader oku; string writeThisis; //----------------------------------------------------------------------------- oku = File.OpenText("dosya1.txt"); StreamWriter SW = File.CreateText("dosya2.txt"); SW.AutoFlush = true; int _line = 0; int LineBUFFER = 40000; string[] Lines = new string[LineBUFFER]; int lineCount = 0; while (!oku.EndOfStream) { _line = 0; while ((yazi = oku.ReadLine()) != null && _line < LineBUFFER) { Lines[_line] = yazi; _line++; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < _line; i++) { metin = Paket(Lines).Split(';'); hn = Convert.ToDecimal(metin[1]) + Convert.ToDecimal(metin[2]); sn = Convert.ToDecimal(metin[3]) + Convert.ToDecimal(metin[4]); writeThisis = (hn * sn).ToString(); sb.AppendLine(writeThisis); } SW.WriteLine(); lineCount += _line; } SW.Close(); } private static string Paket(string dizi) { string eko = ""; string[] Paket = dizi.Split(); for (int i = 0; i < Paket.Length; i++) { if (Paket != "") { eko += Paket + ";"; } } return eko; } private static string edit(string datam) { string oks; oks = datam.ToString(); return oks; } |
Hocam sorunun cevabi bu kitapda sakli < Resime gitmek için tıklayın > |
Bu islem tek threadda zor gibi. Ama yine de nosql konusunu bir arastirin. 20 30 sn den fazla surecek bi isleme benzemiyor. |
Dostum stringBuilder sınıfı kullanman çok yerinde olmuş. string birleştirirken += kullanmayı unut. Bunu yaparken her seferinde "string mi la bu,ha stringmiş,yabıştırayım" der bilgisayar. stringBuilder sınıfının string eklemede,birleştirmede kullanılan metodları var,onları kullan. Tür kontrollerinden kurtulmuş olursun. Bu senin string işleme hızını abartısız ve objektif şekilde 3 e katlar. Yukarıda AppendLine 'ı alttaki metoda da uygula. Bir de,metodlara bölmüşsün,bölme. Aynı kod bloğunun içinde olsun. Aksi halde her seferinde ramden yer ayrılır,remdeki yer boşaltılır,ayrılır,boşaltılır... |
Bu tür işlemlerde PERL dilinin çok hızlı olduğunu duymuştum onu deniyebilirsin. |
Foruma fazla takılamıyorum. Ama Moribito'nun cevaplarını görüyorum. Bu kişinin yanıtlarını her zaman dikkate alın derim. StringBuilder, string'den kat ve kat hızlı çalışır ayrıca kod okunurluğunu artırır. EDİT: Bir StringBuilder sınıfının alabileceği en yüksek boyut, 2.147.483.647 (int32 max değeri) (bu değeri artırmanın bir yolu var mı, yani int64 yapılabilir mi bilmiyorum, bilen varsa söylerse sevinirim, bende öğrenmiş olurum ![]() Ayrıca StopWatch sınıfını kullanarak döngülerinde hız testi yapabilirsin, hangi kodda çok zaman harcanıyor bulmanda yararlı olur. StringBuilder sınıfının metotları araştır. (append, appendline vs... appendformat) , birde bazı özelliklerini öğren (capacity gibi) |
Herkese çok teşekkür ederim. Evet Moribito'nun uyarısını dikkate alıp stringbuilder üzerinde yoğunlaşarak ve elektro_gadget gibi diğer arkadaşların önerilerini kendimce uygulayarak süreyi 20 dk civarına düşürdüm. Sadece nosql konusunda pek birşey yapamadım. Beni aşıyor biraz :) Hala peşindeyim bunu daha kısaltmanın :) Bizim müdürün yıllar önce sanıyorum basicde yazdığı, şu an 64 bitte çalıştıramıyorum dediği console algoritmayı paylaşmak belki faydalı olabilir. Tabi ben yukarıda sadece datayı aldığımı basit bir işlem yapıp yazdırmayı danıştım. Aradaki hesaplamaları yapabilirim diye. Bu kodlarda arada farklı hesaplar yapmakta. Önemli olan bunun kadar neden hızlı birşeyler yazamadığım :) hala benden 5 kat hızlı çalışıyor aşağıdaki.
Bu da benim yazdığım algoritma bozuntusu :) elbette windows aplikasyonu olduğu için müdürünkünden daha uzun :
Acaba daha başka ne yapabilirim? |
Algoritma planım oldukça basit:
1.dosya.txt den datayı satır satır al, her satır için rutin hesap işlemlerini gerçekleştir, çıktıyı 2.dosya.txt'ye yazdır.
Büyük bir heyecanla yaptığım exe'yi müdüre gönderdim.
Müdür ise 100 milyon satırlık (her bir satır ondalıklı kısımlar dahil 8 haneden oluşan boşlukla ayrılmış 6 sutun içeriyor) txt dosyasını çok yavaş işlediğini söyleyerek tepki gösterdi. Olmamış bu dedi :)
Biraz bozuldum ama pes etmek istemiyorum. Durumu telafi etmek adına uzun süredir internette çözüm arıyorum. Müdürün iddiası 100 milyon satırın hesabını 5-6 dk içinde yapan bir .exe yazmış geçmişte.
Ancak bu .exe dosyası 64 bit makinalarda çalışmayan ve basic diliylemi ne yazmış. Güncel yazılım dillerini öğrenecek yaşı geçtiğini düşündüğünden bu ulvi görevi bana verdi
C# bilgim amatör seviyededir. Ama bugüne kadarki yazdığım programcıklar beni hiç yarı yolda bırakmadı.
Merak ettiğim şunlar:
1-) C# console ile C# windows aplication arasında hız açısından fark olur mu?
2-) Gerçekten her biri 8 karakter içeren 6 sutundan oluşan 100 milyon satır bir .txt dosyasından alınıp başka bir .txt dosyasına 5-6 dk. da yazdırmak mümkün müdür? (müdür müdür müdür
3-)Bir for döngüsü ile 100 milyona kadar artan i değerini bile bir .txt dosyasına yazdırmak 1 saati geçiyor. Bu normal midir?
Algoritmamın basitleşmiş hali şu şekildedir:
Yardımlarınızı, eleştirilerinizi, tavsiyelerinizi ve önerilerinizi bekliyorum.
< Bu mesaj bu kişi tarafından değiştirildi tatari81 -- 14 Mart 2014; 14:26:31 >