Serializacja dużych obiektów

Serializacja dużych obiektów
andrzej.kmicic
  • Rejestracja:prawie 12 lat
  • Ostatnio:8 miesięcy
  • Postów:96
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 :

Kopiuj
[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 ?.

Kopiuj
        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

fourfour
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 9 lat
  • Postów:627
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...

andrzej.kmicic
  • Rejestracja:prawie 12 lat
  • Ostatnio:8 miesięcy
  • Postów:96
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 :

Kopiuj
            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

ŁF
Zauważ, że konstruktor listy przyjmuje pewien parametr. Podanie jego odpowiedniej wartości może znacznie przyspieszyć operację dodawania elementów do listy.
andrzej.kmicic
Mówisz o konstruktorze typu : List<T>(Int32) czy o ustawieniu właściwości Capacity ?
dam1an
Wciąż nie rozumiem po cholerę Ci te dane.
RE
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:około rok
0

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

Zobacz pozostały 1 komentarz
RE
andrzej.kmicic
To też pisałem długie listy !.
RE
Zależy od stu innych rzeczy, stąd prosiliśmy o sprecyzowanie problemu (bo bez tego nie możemy określić czy to twoje konkretne rozwiązanie ma sens).
andrzej.kmicic
Ok, więc czekam. Głównie chodzi o to czy cache listy obiektów, w tym konkretnym przypadku daje jakiekolwiek korzyści.
fourfour
To zależy. :D
YU
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
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.


andrzej.kmicic
O(1), znaczy pętla w petli ?. To mnie nie urządza,przynajmniej chodzi mi o algorytm chociażby wywoływany : int[] komb = combination(int n,int k); jeżeli dysponujesz ciekawym źródłem, chętnie skorzystam. Nie mam pojęcia o bardzo współczesnych komputerach ale ten czas wykonania wydaje się bardzo optymistyczny. Rzuć przykładem to pewnie będę miał przyczynek aby zmienić komputer :-).
n0name_l
A jestes w stanie napisac taki kodzik, zeby sie zmiescic z tym w kilkudziesieciu milisekundach?
andrzej.kmicic
Algorytm ze strony http://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G generuje u mnie na jednym rdzeniu ~17 sekund ale gołą listę bez tworzenia klasy no i bez drukowania. Z drukowaniem to trzeba odpuścić i spokojnie można iść na duże piwo. To algorytm sekwencyjny więc z natury szybszy. Ale jak zażądasz np. generacji na numer kombinacji (dowolnie z zakresu 1 do C(n,k) i z wyborem leksykalna lub koleksykalna to te moje 50 sekund wydaje się OK. To jednak dużo, dlatego zainteresowany jestem keszowaniem.
YU
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
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


edytowany 1x, ostatnio: yurai
andrzej.kmicic
Ale tu zdaje się gadamy w C# ??? a podany link to C++ ...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.