Tablice a pamięć

0

Witam,
Mam problem -> rozwiąże go na pewno sam, ale może pomożecie.
Aplikacja pobiera do pamięci zawartość z pliku i ją modyfikuje (nadaje jej pewną maskę).
Po czym zapisuję zmodyfikowaną wersję do pliku. Wręcz banalny programik -> taki formatter logów można powiedzieć.

Jedyny problem to pamięć. W sumie się nie dziwię jeżeli wiecie jak działa <vector> .

Problemu nie mam gdy mam do czynienia z plikiem przykładowo 300 linijkowym (taki testowy).

Problem jest gdy w rzeczywistości operuję na pliku 30 000 linijkowym.

Mam obejście na to -> zapisać każdy element iteracyjny do wspólnych plików a potem z nich odczytywać (można by powiedzieć że zamiast RAM wykorzystuje HDD). A po całym procesie "tymczasowe pliki" usunąć.
ALE... nie chciałbym marnować czasu i czy może ktoś polecić mi najbardziej optymalny kontener względem pamięci ?

#include <array>  // <-- odpada bo nie mam w kompilatorze standardu C++11
#include <list> 
#include <vector>  // <-- odpada
#include <ext/slist>
#include <set>

Znacie jakieś zbiory najbardziej optymalne, dla nieznanej ilości danych, kontenery ?

Sprawdzę jutro <list> , <set> i w ostateczności listę jednokierunkową <ext/slist>, któraś z nich zadziała może to dam wam znać.
Ale z kwestii czysto teoretycznej moglibyście mi doradzić jak to zoptymalizować?

Dla ciekawskich: Jest to wyexportowany do pliku txt zbiór logów który muszę sformatować pod siebie. Jeżeli komputer pracuje ~3 lata to takie eventy są w dużej liczebności ;)

Czemu nie <vector> ? Działa on dynamicznie -> alokuje on pamięć przykładowo "n bajtów", gdy procesowo tę granicę przekraczam
vector rezerwuje kolejne tyle co poprzednio (tutaj 2n). Przy kolejnym przekroczeniu będzie (4n) itd. I wydaje mi się że główny problem tkwi w tym że program podczas rezerwacji "sterty" (pamięci podręcznej) dla siebie, jest na tyle mało pazerny że vector przekracza ją w pewnym momencie i sypie mi się program. Albo kompilator narzuca pewne ograniczenie ? -> NIE WIEM. Ale śledzę działanie programu i pamięć RAM ma ciągle ponad 50% wolnej przestrzeni -> podobnie CPU ;P

Obejście mam ale wolałbym zrobić to na lenia zamiast modyfikować pół kodu. Macie jakieś propozycję odnośnie tych zbiorów?

1

przy vectorze możesz z góry ustawić ile na początku ma zarezerwować pamięci. Dopiero po przekroczeniu tej zwiększy pamięć

0

Może zdefiniuj swój własny allocator ?

0

Jeżeli coś ci się sypie w vector<>'ze przy 300 tysiącach to znaczy problem masz gdzie indziej.
Wg zajmowanej pamięci vector jest najbardziej oszczędny.
Podaj algorytmy którymi się posługujesz to można będzie coś doradzić.

0

Bez sensu odkrywać ponownie Amerykę ;)
W sumie jest takie coś jak metoda resize() . :D

Kod:

void LogFormatting(void)
{
    using namespace std;

    ifstream pobieram("events.txt");            //try to read file
    ofstream tworze("formattedEvents.txt");        //try to create new file
    if(!tworze)
    {
        cout << "Error! Can not create outfile.";
    }
    else
    {
        if(!pobieram)                                //try open file
        {
            cout << "Error! Can not read events.txt!" ;
        }
        else                                        //everythink is OK
        {
            string line="";                            //variable for actually line
            string namePC="";                            //first line in log file
            bool bNamePC=(bool)0;
            vector<string> vectorEvents(0);
            vector<int> eventCount(0);                //array for count events
            int i=0;
            while(getline(pobieram, line))            //assign actually line from 'pobieram' to 'line' 
            {
                //cout << line.substr(0,6);
                if(line.substr(0,6)=="Event[")        //is new event ?
                {
                    //do nothing

                    //vectorEvents.push_back(line);
                    //eventCount.push_back(i);
                }
                else
                {                                    //let's save only interesting values (description below)
                                                    //I am doing it now, because I do not want to book memory for useless data.
                    if(line.substr(0,12)=="  Log Name: ")
                    {
                    //do nothing
                        line="";
                    }
                    else
                    {
                        if(line.substr(0,10)=="  Source: ")
                        {
                            //cut caption
                            line=line.substr(10);
                        }
                        else
                        {
                            if(line.substr(0,8)=="  Date: ")
                            {
                                //cut caption
                                line=line.substr(8);
                            }
                            else
                            {
                                if(line.substr(0,12)=="  Event ID: ")
                                {
                                    //cut caption
                                    line=line.substr(12);
                                }
                                else
                                {
                                    if(line.substr(0,8)=="  Task: ")
                                    {
                                        //do nothing
                                        line="";
                                    }
                                    else
                                    {
                                        if(line.substr(0,9)=="  Level: ")
                                        {
                                            //cut caption
                                            line=line.substr(9);
                                        }
                                        else
                                        {
                                            if(line.substr(0,10)=="  Opcode: ")
                                            {
                                                //do nothing
                                                line="";
                                            }
                                            else
                                            {
                                                if(line.substr(0,11)=="  Keyword: ")
                                                {
                                                    //do nothing
                                                    line="";
                                                }
                                                else
                                                {
                                                    if(line.substr(0,8)=="  User: ")
                                                    {
                                                        //do nothing
                                                        line="";
                                                    }
                                                    else
                                                    {
                                                        if(line.substr(0,13)=="  User Name: ")
                                                        {
                                                            //do nothing
                                                            line="";
                                                        }
                                                        else
                                                        {
                                                            if(line.substr(0,12)=="  Computer: ")
                                                            {
                                                                //do nothing but at the first time save to variable
                                                                line="";
                                                                if(bNamePC==(bool)0)
                                                                {
                                                                    bNamePC=(bool)1;
                                                                    namePC=line.substr(12);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                if(line.substr(0,15)=="  Description: ")
                                                                {
                                                                    //do nothing, because next line is value of description
                                                                    line="";
                                                                }
                                                                else
                                                                {
                                                                    //rest -> so it's value of description
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if(line!="")
                    {
                    vectorEvents.push_back(line);   //ładuj interesującą mnie linie do vector'u
                    }
                }
/*
STRUCTURE OF vectorEvents[]

vectorEvents[n]        = "Event[x]:"                            <-- do not copy to file
vectorEvents[n+1]    = "Source: /.../"                        <-- cut "Source: "
vectorEvents[n+2]    = "Date: rrrr-mm-ddThh:mm:ss:sss"        <-- cut "Date: " and change "T" (between date and time) to space " "
vectorEvents[n+3]    = "EventID: /.../"                        <-- cut "EventID: "
vectorEvents[n+4]    = "Level: /.../"                        <-- cut "Level: "
vectorEvents[n+5]    = "Description: /.../"                    <-- only this will be full copied.
*/
                i++;    
            }

// TUTAJ JUZ NIE DOCHODZI :) 
// czyli w trakcie ładowania do vectoru ;)


        }
    }
}

pewnie nie chce wam się tego analizować, przetestuję jutro tę metodę resize() albo reserve(), jak nie pomoże to na <list> spróbuję to sprawdzić bo z teorii wiem że lista jest najbardziej optymalna (również <set>) ;) W ostateczności zrobię to na plikach. I dam wam odpowiedź żeby na przyszłość googlowicze nie mieli problemu ;P

PS: ta liczba "if'ów" jest specjalnie zrobiona bo gdy będę chciał zmodyfikować program w taki sposób że wartości które nie wyświetlałem nagle będą mi potrzebne, to wprowadze małe poprawki :)

0

Zawartość pliku wygląda tak:

Event[n]:
Log Name: /.../
Source: /.../
Date: /.../
Event ID: /.../
Task: /.../
Level: /.../
Opcode: /.../
Keyword: /.../
User: /.../
User Name: /.../
Computer: /.../
Description:
/.../
Event[n+1]:
Log Name: /.../
Source: /.../
Date: /.../
Event ID: /.../
Task: /.../
Level: /.../
Opcode: /.../
Keyword: /.../
User: /.../
User Name: /.../
Computer: /.../
Description:
/.../

Jak komuś się nudzi, to niech prze klei to 150 000 razy i pobawi <vector> ;)

Dla ciekawskich formatuję plik wynikowy polecenia cmdlet:

wevtutil qe System /f:text > anyName.txt

0

Nadal nie widzę przyczyny ładowania tego do vectora. To co pokazałeś można bez problemu zrobić wiersz po wierszu.

1
  1. Wczytujesz wiersz z pliku -> modyfikujesz go tak jak trzeba -> Zapisujesz do pliku :)
  2. Dlaczego tak dużo else? Nie możesz dać else if?
  3. Wypchnij to parsowanie do osobnej funkcji, bo śmieci i zmniejsz ilość linijek, bo jest nieczytelne:
if( strncmp( str.c_str(), "wartosc1:", strlen("wartosc1" ) == 0) ) file.write( str.c_str()+strlen("wartosc1)", str.length() - strlen("wartosc1")) );
else if( strncmp( str.c_str(), "wartosc2:", strlen("wartosc2" ) == 0) ) file.write( str.c_str()+strlen("wartosc2"), str.length() - strlen("wartosc2")) );
else //Skoro nic nie robisz to else jest nie potrzebne.
// if(line.substr(0,11)=="  Keyword: ")
// przy takiej wartości też nic nie robiłeś, więc nawet nie sprawdzasz, czy występuje - chyba, że w przyszłości będziesz coś z nią robić.
// warunki posortuj po prawdopodobieństwie wystąpienie.
// na samej górze te, które najczęściej są spełnione.
0

Mistrzu, ja Cie rozumiem że naginam zasady "prawidłowego" programowania. Ale nie bez sensu każde z osobna to zrobiłem bo za pół roku jak będę chciał poszerzyć albo obciąć formatowanie to będę musiał sobie wszystko przypominać :)

0

Zrobiłem to na plikach tymczasowych w końcu ;) Vector'a mógłbym rozszerzyć -> zajebisty pomysł, dzięki fasadin ale exe'k bedzie działał na komputerach o obciążonej pamięci przez inne procesy. Nie chcę ryzykować potem ani ograniczać innych aplikacji ;P

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