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 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. |
|
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. |
|
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 >> |
|
maly |
» 2015-01-09 19:10:27 Wrzuć plik do stringstream i operuj na nim, będziesz miał taką samą funkcjonalność jak na fstream. 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:) |
|
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. |
|
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). |
|
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? |
|
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. |
|
« 1 » 2 3 |