Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

C# - Optymalizacja zapisu do pliku bardzo dużej ilości próbek

02 Cze 2013 19:27 3447 16
  • Poziom 14  
    Witam.
    Jak dotąd nie miałem problemów z zapisem dopóki nie mam do zapisu 30x2000 próbek do pliku txt. Zapis trwa jakieś 1 min.

    Przechowuje dane w:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    Intów jest 30 double 2000.

    Inicjuje dane dla testu tak:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Zapisuje dane tak:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Przykładowy plik wygląda tak:
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Można by to jakoś zoptymalizować? Mam procesor 2 rdzeniowy 4GB ram.
    Albo może macie jakieś pomysły jak informować użytkownika że zapis jest w toku.
  • Pomocny post
    Poziom 40  
    Na pierwszy rzut oka widać, że robisz podstawowy błąd w łączeniu stringów. Wszędzie o tym piszą, ale jak widać za mało... ;)

    Jak masz więcej niż +/- 10 złączeń tekstu, nie rób nigdy:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    czy
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    tylko użyj klasy StringBuilder i metody Append(), AppendLine() i / lub AppendFormat().
    Klik

    Ja bym też zamiast odwołań do elementów słownika (po co? -dodatkowy koszt), wykorzystał dwie zagnieżdżone pętle for each.
  • Poziom 14  
    marcinj12 napisał:
    Jak masz więcej niż +/- 10 złączeń tekstu, nie rób nigdy:
    Kod C# - [rozwiń]text += "\r\n";
    czy
    Kod C# - [rozwiń]text += RateSamples
    tylko użyj klasy StringBuilder i metody Append(), AppendLine() i / lub AppendFormat().

    Niesamowite teraz to czas zapisywania jest niezauważalny dla użytkownika :D Dzięki!
    Dopiero teraz się dowiedziałem po co używać klasy StringBuilder :P

    Dżyszla napisał:
    A tak ogólnie - zacznij od zlokalizowania wąskiego gardła. Cały zapis to kilka bloków o długim czasie - zacznij od profilowania tych fragmentów i optymalizacji najdłużej trwających.

    Nigdy nie używałem narzędzi do sprawdzania wydajności kodu :D teraz w sumie aplikacja działa jak należy, ale w przyszłości przydałoby się tego nauczyć :)
  • Poziom 33  
    A po co tworzyć wielkiego stringa skoro można zapisać od razu do pliku?
  • Poziom 14  
    Czyli w pętli miałbym robić dopisywanie do pliku i to by miało większą wydajność zapisu niż skorzystanie z StringBuildera?
  • Poziom 33  
    Sprawdź. Z ciekawości sprawdziłem u siebie. Różnica jest na poziomie kilku ms (dla zapisu pliku takiego jak podałeś <mała poprawka w poniżej>). O dziwo bezpośredni zapis może działać wolniej - w trybie cichym - ok. 2ms. W normalnym trybie ok. 6ms szybciej. ;)
    Najwięcej czasu zajmuje przerobienie danych na stringa.
  • Poziom 14  
    Może i bym sprawdził, ale nigdy nie mierzyłem czasu wykonania kodu, więc nawet nie wiem jak to się robi właściwie ;)
  • Poziom 40  
    D12 napisał:
    Może i bym sprawdził, ale nigdy nie mierzyłem czasu wykonania kodu, więc nawet nie wiem jak to się robi właściwie :wink:
    Można na różne sposoby, ja to zwykle robię takim kodem (pętla jest opcjonalna, przydaje się przy pomiarze czasu ultra-krótkich operacji)
    Kod: csharp
    Zaloguj się, aby zobaczyć kod
  • Poziom 33  
    Możesz użyć klasy System.Diagnostics.Stopwatch.

    Dodano po 6 [minuty]:

    Spóźniłem się... Mierzyłem to właśnie tak, jak pokazał marcinj12. Obie wersje wewnątrz pętli.
  • Poziom 11  
    Możesz też jeszcze sprawdzić czy nie było by szybciej użyć klasy

    StreamWriter

    i korzystać z metod Write i WriteLine

    w ten sposób nie trzeba tworzyć obiektu z tekstem.

    Drugie podejście to może warto by było użyć jakiegoś serializera do xmla albo pliku binarnego i zapisywać wszystko jak leci.
  • Poziom 33  
    Rozpędziłem się z WriteLine/AppendLine w moich testach (dałem wszędzie). Teraz przyspieszenie jest większe i dodatnie w obu wcześniej wyróżnionych przypadkach.

    Icen napisał:
    Możesz też jeszcze sprawdzić czy nie było by szybciej użyć klasy

    StreamWriter
    Właściwie to o tym właśnie pisałem... ;)
  • Poziom 16  
    A co byście powiedzieli(chciałbym aby większość się wypowiedziała) na to by zrobić własne rozszerzenie ?
    bo rozumiem że chce mieć pliczek .txt do szybkiego podglądu oraz aby aplikacja szybko zapisywała dane. Kolega Icen wspominał o serializacji co jest świetnym pomysłem do szybkiego zapisu danych. Ale nie jeśli chce się uzyskać zrozumiały .txt
    dlatego wpadłem na pomysł stworzenia 2 aplikacji do odczytu tego rozszerzenia.
    potem wystarczy tylko podpiąć rozszerzenie pod tą aplikacje(jeszcze trzeba arg[] wypełnić) i mamy fajny system.
  • Poziom 33  
    Jeśli takich plików ma używać tylko Twoja aplikacja możesz użyć rozszerzenia .dat. Warto w takim pliku umieścić nagłówek i sprawdzać, czy plik zawiera poprawne dane.
    Nie wiem tylko po co chcesz tworzyć 2 aplikacje do odczytu. :P
  • Poziom 14  
    Dane zapisuje tylko po to by móc je przenieś potem do arkusza kalkulacyjnego i matlaba lub czego tam użytkownik programu by nie chciał. Wiec txt jest najbardziej uniwersalne.
  • Poziom 11  
    to z txt przerzuć się na csv

    excel i matlab radzą sobie z tym rozszerzeniem prawie automatycznie

    Dodano po 5 [minuty]:

    Pomysł przemko07 jest niezły można by wykorzystać serializator binarny i wtedy po pierwsze rozmiar pliku maleje kilkukrotnie a po drugie można w łatwy sposób przenosić te dane do innych programów poprzez showek

    znaczy otwieramy nas plik w naszym 2 programiku wyświetla nam się textbox gdzie dane są poukładane w tabelce rozdzielone tabem i kopiujemy je gdzie chcemy czy.

    Zalety to:
    bez programu do odczytu o wiele trudnej będzie się do pliku dobrać
    rozmiary plików będą znacznie mniejsze

    wady
    bez programu do odczytu o wiele trudnej będzie się do pliku dobrać
    drugi program trzeba napisać
  • Poziom 14  
    Dobra zamykam starocie. Trzeba używać StringBuildera i tyle w temacie.