Serializacja dużych obiektów

Serializacja dużych obiektów
andrzej.kmicic
  • Rejestracja:prawie 12 lat
  • Ostatnio:7 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:7 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:11 miesięcy
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:ponad 16 lat
  • Ostatnio:około 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:ponad 16 lat
  • Ostatnio:około 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++ ...
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)