Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
Hardwire
Založen: 04. 09. 2007 Příspěvky: 117
|
Zaslal: 23. prosinec 2008, 23:44:29 Předmět: Cteni binarnich dat ze streamu |
|
|
Ahoj,
zajimalo by me, jakym zpusobem ctete v C++ data ze streamu tak, aby to bylo efektivni. Potrebuju je mit po nacteni v jednom souvislym bloku pameti, ale samozrejme predem neznam pocet bytu, ktery nactu.
Momentalne to soupu po jednom bytu do vectoru a z nej to pak pres memcpy preleju do vyslednyho bloku pameti, ale cteni po jednom bytu je dost pomaly (nejsem si jistej jestli vinou kontroly streamu na EOF, ctenim toho bytu nebo jeho zapisem do vectoru). Jediny reseni, co me napadlo, je nacitat to po vetsich blocich (~1KB) pres read, pointery na tyhle bloky strkat do vectoru a nakonec to slejt do jednoho velkyho bloku. Ale moc se mi to nelibi  |
|
Návrat nahoru |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 24. prosinec 2008, 05:20:10 Předmět: Re: Cteni binarnich dat ze streamu |
|
|
Hardwire napsal: |
Ahoj,
zajimalo by me, jakym zpusobem ctete v C++ data ze streamu tak, aby to bylo efektivni. Potrebuju je mit po nacteni v jednom souvislym bloku pameti, ale samozrejme predem neznam pocet bytu, ktery nactu.
Momentalne to soupu po jednom bytu do vectoru a z nej to pak pres memcpy preleju do vyslednyho bloku pameti, ale cteni po jednom bytu je dost pomaly (nejsem si jistej jestli vinou kontroly streamu na EOF, ctenim toho bytu nebo jeho zapisem do vectoru). Jediny reseni, co me napadlo, je nacitat to po vetsich blocich (~1KB) pres read, pointery na tyhle bloky strkat do vectoru a nakonec to slejt do jednoho velkyho bloku. Ale moc se mi to nelibi  |
zapisuju primo do pole nikoliv vectoru - a to tak ze kdyz pole nestaci zvetsim ho 2x skrze realloc - tim ze se zvetsi 2x (tedy exponencialne) a nikoliv tupe pouze o nejaky kousek je tech re-alokaci minimum |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 24. prosinec 2008, 08:34:26 Předmět: |
|
|
na toto sa da pouzit aj ten vektor aby sme ostali v peknom C++. potom to bude vyzerat nejak takto
kód: |
std::vektor<char> data;
while(vstup!=EOF)
{
data.push_back(read);//nacitame zapiseme do vektora
if(data.capacity()==data.size())data.resize(data.size()*2);//ak sa naplni vektor tak ho rucne zvetsime
} |
_________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 24. prosinec 2008, 08:58:13 Předmět: |
|
|
pozor - musi se nacitat unsigned char jinak to dela bordel. to je totiz ta spravna hodnota bytu. |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 24. prosinec 2008, 10:37:34 Předmět: |
|
|
Pokud vím, tak u všech trochu rozumných implementací vectoru (MS, GCC, DM) už push_back sám o sobě zdvojnásobuje velikost rezervovaného místa. Tuším dokonce, že tahle složitost je garantovaná standardem (amortized constant time nebo tak nějak). A možná, že to tak funguje i pro .insert (.back (), ...); ...no, není přece tak složité si to ověřit jednoduchým prográmkem, že? _________________ WWW | GitHub | TW |
|
Návrat nahoru |
|
 |
quas4
Založen: 18. 10. 2007 Příspěvky: 199
|
Zaslal: 24. prosinec 2008, 11:14:58 Předmět: |
|
|
Tringi napsal: |
není přece tak složité si to ověřit jednoduchým prográmkem, že? |
nebo se rovnou podivat zdrojaku, ne? |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 24. prosinec 2008, 11:28:49 Předmět: |
|
|
Tringu> Tak to asi změnili specifikaci ne? Protože pokud vím, tak to nebylo zdvojnásobování, ale něco mnohem menšího. Samozřejmě amortizovaný to je furt, ale v praxi je ta konstanta (amortizovaná cena) mnohem vyšší než u zdvojnásobování, spotřeba paměti je pak nižší. Proto si myslím, že ruční zdvojnásobování má stále smysl, pokud jde o rychlost.
Hardwire> Co to je za stream, že neznáš počet bajtů?
U souborů můžeš udělat seek na konec souboru, zjistit si pozici = počet bajtů. Pak seek na začátek souboru a načíst celý soubor. _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Hardwire
Založen: 04. 09. 2007 Příspěvky: 117
|
Zaslal: 24. prosinec 2008, 11:35:22 Předmět: |
|
|
Eosie napsal: |
Hardwire> Co to je za stream, že neznáš počet bajtů?
U souborů můžeš udělat seek na konec souboru, zjistit si pozici = počet bajtů. Pak seek na začátek souboru a načíst celý soubor. |
Momentálně ho otvírám ze souboru, ale plánuju to pak pouzit na cteni dat z neceho co mi prijde po siti. Ale asi tam udelam nejakou specializaci pro pripad, kdy pocet dat predem znam. I v pripade posilani dat pres sit (nebo cteni z velkyho zapackovanyho souboru) si muzu velikost dat, ktery budou nasledovat, nekam poznamenat. |
|
Návrat nahoru |
|
 |
quas4
Založen: 18. 10. 2007 Příspěvky: 199
|
Zaslal: 24. prosinec 2008, 21:36:02 Předmět: |
|
|
Eosie napsal: |
Tringu> Tak to asi změnili specifikaci ne? Protože pokud vím, tak to nebylo zdvojnásobování, ale něco mnohem menšího. |
Nezmenili. V libstdc++v3 (4.3 i 4.1) je to tak stale (cisly 4.3 a 4.1 dale myslim verze g++ ke kterym se vztahuji prislusne revize libstdc++v3), viz bits/stl_vector.h funkce _M_check_len() (u 4.1 je vypocet provaden jinde) + porozhlednuti odkud se vola..
Zajimavejsi je to u ext hash_* (has_set, hash_map), zde se uz 4.1 a 4.3 (unordered_set, unordered_map) dost lisi. Velikost alokovane pameti pro "buckets" jde v 4.1 hezky po tabulce prvocisel viz hashtable.h a funkce __stl_next_prime() - je to velmi slusny zrout pameti! 4.3 je o neco setrnejsi ale potyka se jinymi vadami na krase (holt vestina specha k c++0x).
Takova znalost neni pro c++ vyvojare (ktery to mysli vazne) na skodu. Jeste ze uz v c++ moc nepisu  |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 28. prosinec 2008, 23:34:31 Předmět: |
|
|
Aha, tak to je tím, že nepoužívám G++, tzn. se mě ta norma stejně netýká.
Ve VC++ 2008 roste kapacita vektoru takto: 1, 2, 3, 4, 6, 9, 13, 19, 28, 42, 63, 94, 141, 211, 316, 474, 711, 1066 _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 29. prosinec 2008, 00:49:30 Předmět: |
|
|
Myslím, že ať je to ×1.5 nebo ×2, tak rozdíl při reálné aplikaci nebude ani trochu znatelný. Pokud se tohle plnění nedělá tisíckrát za snímek, pak ani zjištění velikosti a .reserve() vnímanou rychlost neovlivní.
Abych se vrátil k původní otázce. Pokud to množství načítaných dat bude řádově desítky megabajtů, pak už se pravděpodobně projeví overhead volání funkcí. Hardwire, píšeš že pak používáš memcpy abys to někam šoupnul, to bych řekl že je zbytečné, je lepší to nechat ve vectoru, případně na závěr udělat: std::vector <unsigned char> (v.begin (), v.end ()) .swap (v); ...Čtení po blocích a pak vkládání (pomocí .insert ()) je určitě vhodné řešení pro velké sady dat. _________________ WWW | GitHub | TW |
|
Návrat nahoru |
|
 |
Hardwire
Založen: 04. 09. 2007 Příspěvky: 117
|
Zaslal: 29. prosinec 2008, 00:56:13 Předmět: |
|
|
Tringi napsal: |
Abych se vrátil k původní otázce. Pokud to množství načítaných dat bude řádově desítky megabajtů, pak už se pravděpodobně projeví overhead volání funkcí. Hardwire, píšeš že pak používáš memcpy abys to někam šoupnul, to bych řekl že je zbytečné, je lepší to nechat ve vectoru, případně na závěr udělat: std::vector <unsigned char> (v.begin (), v.end ()) .swap (v); ...Čtení po blocích a pak vkládání (pomocí .insert ()) je určitě vhodné řešení pro velké sady dat. |
Byly to radove stovky KB, takze nic extra velkyho. Nicmene kdyz jsem to upravil tak, ze se to nacita po 1K blocich pres read, tak se to nekolikanasobne zrychlilo. Problem nemusel bejt nutne v samotnym volani funkci, ale treba v tom, ze cteni po 1 bytu je proste pomaly...
Nacteny data potrebuju mit v poli bytů, takze proto to kopirovani...jo, kopirovat to takhle pres vector misto memcpy me nenapadlo, tak dik za info  |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 29. prosinec 2008, 13:45:37 Předmět: |
|
|
Spíš čti soubory po 512kB blocích. Cokoliv menšího dnes už asi nemá smysl. Možná bych přesto radši sáhl po memcpy, může být rychlejší než vector::swap. _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
|