.[ ČeskéHry.cz ].
Cteni binarnich dat ze streamu

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Hardwire



Založen: 04. 09. 2007
Příspěvky: 117

PříspěvekZaslal: 23. prosinec 2008, 23:44:29    Předmět: Cteni binarnich dat ze streamu Odpovědět s citátem

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 Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 24. prosinec 2008, 05:20:10    Předmět: Re: Cteni binarnich dat ze streamu Odpovědět s citátem

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 Smile


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
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 24. prosinec 2008, 08:34:26    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 24. prosinec 2008, 08:58:13    Předmět: Odpovědět s citátem

pozor - musi se nacitat unsigned char jinak to dela bordel. to je totiz ta spravna hodnota bytu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 24. prosinec 2008, 10:37:34    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
quas4



Založen: 18. 10. 2007
Příspěvky: 199

PříspěvekZaslal: 24. prosinec 2008, 11:14:58    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 24. prosinec 2008, 11:28:49    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Hardwire



Založen: 04. 09. 2007
Příspěvky: 117

PříspěvekZaslal: 24. prosinec 2008, 11:35:22    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
quas4



Založen: 18. 10. 2007
Příspěvky: 199

PříspěvekZaslal: 24. prosinec 2008, 21:36:02    Předmět: Odpovědět s citátem

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 Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 28. prosinec 2008, 23:34:31    Předmět: Odpovědět s citátem

quas4 napsal:
Nezmenili.

Aha, tak to je tím, že nepoužívám G++, tzn. se mě ta norma stejně netýká. Smile

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 29. prosinec 2008, 00:49:30    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Hardwire



Založen: 04. 09. 2007
Příspěvky: 117

PříspěvekZaslal: 29. prosinec 2008, 00:56:13    Předmět: Odpovědět s citátem

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 Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 29. prosinec 2008, 13:45:37    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna