Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Bardzo powolne wczytywanie pliku

Ostatnio zmodyfikowano 2015-01-10 15:45
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
Bardzo powolne wczytywanie pliku
» 2015-01-09 18:22:55
Cześć, właśnie próbuje zoptymalizować trochę wczytywanie modelu z pliku. Najpierw aktualny kod
C/C++
std::fstream plik( fname.c_str(), ios::in | ios::binary );
if( !plik )
     return false;
else
{
    UINT actualSubset = 0;
   
    m_subsets.push_back( ModelSubset() );
   
    m_subsets[ actualSubset ].m_model = new VertexModel();
    VertexModel * model = m_subsets[ actualSubset ].m_model;
   
    vector < uVector3 < float >> Position;
    vector < uVector < float >> TexCoord;
    vector < uVector3 < float >> Normal;
   
    string cmd;
    plik >> cmd;
   
    Clock myTimer;
    while( true )
    {
       
        if( cmd == "#" )
        {
            getline( plik, cmd );
        }
        else if( cmd == "o" )
        {
            if( actualSubset > 0 )
            {
                model->create( device );
                actualSubset++;
               
                m_subsets.push_back( ModelSubset() );
               
                m_subsets[ actualSubset ].m_model = new VertexModel();
                model = m_subsets[ actualSubset ].m_model;
            }
            else actualSubset++;
           
        }
        else if( cmd == "v" )
        {
            float x, y, z;
            plik >> x >> y >> z;
            Position.push_back( uVector3 < float >( x, y, z ) );
        }
        else if( cmd == "vt" )
        {
            float u, v;
            plik >> u >> v;
            TexCoord.push_back( uVector < float >( u, v ) );
        }
        else if( cmd == "vn" )
        {
            float x, y, z;
            plik >> x >> y >> z;
            Normal.push_back( uVector3 < float >( x, y, z ) );
        }
        else if( cmd == "f" )
        {
            UINT Value = 0;
            Vertex vertex;
            string ilosc;
           
            int pos =( int )( plik.tellg() );
           
           
            getline( plik, ilosc );
           
            int toCount =(( std::count( ilosc.begin(), ilosc.end(), '/' ) ) / 2 );
           
            plik.seekg( pos, ios::beg );
           
            vector < DWORD > myIndices;
           
            for( int iFace = 0; iFace < toCount; iFace++ )
            {
                plik >> Value;
                vertex.setPosition( Position[ Value - 1 ].x, Position[ Value - 1 ].y, - Position[ Value - 1 ].z );
                plik.ignore();
               
                plik >> Value;
                vertex.setTextureCoords( TexCoord[ Value - 1 ].x, 1.0f - TexCoord[ Value - 1 ].y );
                plik.ignore();
               
                plik >> Value;
                vertex.setNormal( Normal[ Value - 1 ].x, Normal[ Value - 1 ].y, - Normal[ Value - 1 ].z );
                if( iFace < toCount ) plik.ignore();
               
                int vID = - 1;
               
                for( int a = 0; a < model->getVerticlesNumber(); a++ )
                {
                    if( model->getVertex( a ) == vertex )
                    {
                        vID = a;
                        break;
                    }
                }
                if( vID == - 1 )
                {
                    model->addVertex( vertex );
                    vID = model->getVerticlesNumber() - 1;
                }
               
                myIndices.push_back( vID );
            }
           
            for( int i = 0; i < myIndices.size(); i++ )
            {
                if( i >= 3 )
                {
                    model->addIndex( myIndices[ 0 ] );
                    model->addIndex( myIndices[ i - 1 ] );
                    model->addIndex( myIndices[ i ] );
                }
                else model->addIndex( myIndices[ i ] );
               
            }
           
        }
       
        plik >> cmd;
        if( plik.eof() )
        {
            model->create( device );
            cout << "Model loaded with time: " << myTimer.getElapsedTime().asSeconds() << endl;
            break;
        }
       
       
    }
   
}
Zastanawiam się co robie nie tak. Ładowanie 5MB modelu (ok. 150000 linijek) trwa jakieś 92 sekundy a dla porównania w Blenderze trwa to mniej niż trzy sekundy! Czemu? To jest szczerze mówiąc śmieszne, żeby 5MB ładowało się tyle czasu.

Edit:
Czy gdybym uruchomił to ładowanie w osobnym wątku to działałoby to szybciej?

Edit x2:
Może być to ważną informacją, bo gdy wypisywałem aktualną wczytywaną linię (pomijam spadek wydajności przez samo wypisywanie) to wczytywały się coraz wolniej. Na przykład od 0-15000 linii bardzo szybko zmieniała się liczba tysięcy a od 130000 linii szybko zmieniała się cyfra setek, jest to dziwne.
P-124500
stryku
» 2015-01-09 18:59:12
Osobny wątek by nic nie dał, a nawet by spowolnił.
Osobny proces dałby taki sam efekt jak jest teraz.

Może głupie pytanie, ale odpalałeś w trybie Release czy Debug?

Taka uwaga tylko, że strumienie są dość wolne ( plik >> cmd itp ). Może skoro pliki duże nie są ( 5 mb pisałeś ) to wczytać cały na raz do RAMu i na nim operować? Wiem, że zniknie dużo udogodnień typu plik >> cmd, ale jeden dostęp dyskowy i potem działanie na w RAMie jest o wiele szybsze niż 150000 dostępów.
P-124502
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2015-01-09 19:10:09
Masz rację, tylko ciężko będzie wtedy pobierać pojedyncze liczby. << removed - bardzo nie na temat >>
P-124504
maly
» 2015-01-09 19:10:27
Wrzuć plik do stringstream i operuj na nim, będziesz miał taką samą funkcjonalność jak na fstream.
C/C++
std::fstream plik( fname.c_str(), ios::in | ios::binary );
std::stringstream ss;
ss << plik.rdbuf();

std::string str;
std::getline( ss, str );

//EDIT
dodałem std::fstream plik(... do przykładu i tada:)
P-124505
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2015-01-09 19:17:38
Niezły pomysł. Jak odczytać cały plik naraz?
Edit: Ok, dzięki, sprawdze.
Edit x2: Teraz plik wczytuje się o 5 sekund dłużej.
P-124506
maly
» 2015-01-09 19:43:24
Nie powinno wykonywać się dłużej, ale jeśli nie przyśpieszyło to push_back może być winny(każde push_back to potencjalna realokacja).
P-124508
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2015-01-09 19:49:00
Zdawałem sobie z tego sprawe, ale jak mam przewidzieć ile będe potrzebował pamięci?
P-124511
pekfos
» 2015-01-09 19:53:55
Użyj I/O z C.

ale jak mam przewidzieć ile będe potrzebował pamięci?
Możesz zapytać system operacyjny o wielkość pliku.
P-124512
« 1 » 2 3
  Strona 1 z 3 Następna strona