Serializacja dużych obiektów

0

Witam

Stworzenie (wygenerowanie) Listy obiektów z zastosowaniem programowania równoległego z wykorzystaniem dwu rdzeni procesora (bo taki posiadam) trwa około minuty. W generacji najwięcej czasu zajmuje procedura generacji wszystkich kombinacji pola ticket. Np. W dużym lotku wygenerowanie wszystkich kombinacji to prawie C(6,49) ~~ 14 milionów kombinacji.

Pomyślałem że jeżeli stworzę rodzinę plików dla wszystkich popularnych kombinacji to Listę można tworzyć jeszcze szybciej wg algorytmu :
Jeżeli plik C_6_49.cache istnieje to :
nie generuj tylko wczytaj listę z pliku.

Właściwie jeżeli się coś tu nadaje się do cachowania struktury w pliku to tylko zapis binarny bo deserializacje tekstowe (json,xml) daja pliki i czasy GigaWielkie. Uzycie BinaryFormater też trwa długo !.

strukrura zapisu :

[Serializable]
class filterInfo {
        public bool filtered { set; get; }  
        public double value { set; get; }
        public double diffvalue { set; get; }
        public filterInfo(bool a=false, double b=0D, double c=0D) {
            this.filtered = a;
            this.value = b;
            this.diffvalue=c;
            }
    }
    
[Serializable]    
class ticketsData {
        public int[]    ticket { set; get; }
        public filterInfo   filterInfo { set; get; }
        public string   filterName { set; get; }
        
        public ticketsData   (int[] iticket,filterInfo ifilterInfo , string ifilterName = "ABC") {
            this.ticket     = iticket;
            this.filterInfo = ifilterInfo;
            this.filterName = ifilterName;
            }        
    }

Ale nie jest tak słodko. Serializacja a bardziej deserializacja dla tak duzych plików trwa przerażajaco długo. Chyba że coś przeoczyłem lub nie wiem ?.
Pomyslałem ze użycie BinaryWriter w zapisie sekwencyjnym powinno zadziałać szybciej ale jak dotąd nie udało mi się nawet to sprawdzić ciągle generuję błędy, albo znów czegoś nie wiem ?.

        public void save(string fname) {
            
            FileStream fileStream = new FileStream(fname, FileMode.Create);
            BinaryWriter binaryWriter = new BinaryWriter(fileStream);
            
            foreach(ticketsData td in this.resultsList) {
                ticketsData td = this.resultsList[0];
                binaryWriter.Write((string)td.filterName);
                binaryWriter.Write((int)td.ticket.Count());
                foreach(int tic in td.ticket)
                    binaryWriter.Write((Int32)tic);
                binaryWriter.Write((bool)td.filterInfo.filtered);
                binaryWriter.Write((double)td.filterInfo.value);
                binaryWriter.Write((double)td.filterInfo.diffvalue);
                }
            binaryWriter.Flush();    
            binaryWriter.Close();
            }

Wydaje się że taki sekwencyjny zapis powinien być najszybszy i działać dobrze ale wciąż generuje błędy.
Może macie link do dobrej i szybkiej procedury zapisu, odczytu sekwencyjnego obiektów, lub jakiś pomysł ?. Bo na razie generacja na zywo wygrywa zdecydowanie.

pozdr
AK

0

Hmm... a w ogóle jaki jest cel takich działań? Co chcesz tak naprawdę osiągnąć, jaki jest realny problem do rozwiązania? Tak z ciekawości pytam...

0
fourfour napisał(a):

Hmm... a w ogóle jaki jest cel takich działań? Co chcesz tak naprawdę osiągnąć, jaki jest realny problem do rozwiązania? Tak z ciekawości pytam...

O tym pisałem, sądziłem ze wczytanie z cache obiektu skróci te minutę generacji (na dwu rdzeniach) i zamiast generować za każdą filtracją od nowa można będzie wczytywać gotowy zestaw 14 milionów z pliku (cache). Ale jak dotąd (próbowałem różnych metod serializacji) generowanie jest najszybsze. Może serializacja niewielkich obiektów daje wymierne efekty ale dla dużych wygląda to blado. Dlatego chciałem się upewnić czy jest moze sposób o tórym nie wiem.
Realny problem to np : w miarę szybko wszystkie kombinacje np C(6,49) wygenerować i zapisać w pliku lub jeżeli plik istnieje to będzie to szybciej, wczytać z pliku (łącznie z podaną struktura klasą). A ogólnie to lubię operacje na liczbach i statystykę.

Bez wchodzenia w szczegóły generacji, wygenerować można dla przykładu listę 14 milionów rekordów :

            List<ticketsData> ticketsList = new List<ticketsData>();

            for (int j=0;j<14000000;j++) {
                int[] ticket = new int[]{1,2,3,4,5,6}; 
                ticketsList.Add(new ticketsData(ticket,new filterInfo(false,0.0D,0.0D)));
                }

oczywiście w przykładzie jest deklaracja kombinacji zdeklarowana na stałe (123...} i trwa trochę krócej niż generowanie kolejnych kombinacji ale jeżeli serializacja a bardziej deserializacja z pliku będzie szybka to można się pokusić aby te same kombinacje były cachowane w plikach.
No i tyle na ten temat, jaśniej chyba nie dm rady.
pozdr
AK

0

To jest już twoja próba implementacji rozwiązania, fourfour pytał o sam problem.

0

W dużym lotku wygenerowanie wszystkich kombinacji to prawie C(6,49) ~~ 14 milionów kombinacji.

Jesli dobrze zrozumiałem problem polega na wygenerowaniu kombinacji 6-el ze zbioru 49-elementowego. Na współczesnym komputerze będzie ono natychmiastowe (przy O(1) per kombinacja spokojnie zmieścisz się w kilkudziesięciu milisekundach. I to na jednym rdzeniu. ).
Nie wiem po co bawić się w serializacje i inne voodoo.

0

A jestes w stanie napisac taki kodzik, zeby sie zmiescic z tym w kilkudziesieciu milisekundach?

Myślę, że taki programik (ten pierwszy) spokojnie da radę (oczywiście bez print-owania i ze zmienionymi n,k):
http://stackoverflow.com/questions/12991758/creating-all-possible-k-combinations-of-n-items-in-c

1 użytkowników online, w tym zalogowanych: 0, gości: 1