gibts irgend wo ne art liste, die sagt, welche c++ befhele schnell und welche langsam sind?
-
hallo
also zwecks optimierung von code auf geschwindigkeit (z.B. wpc)
außer natürlich mathematischen zusammenfassungen kann ja auch mit code optimiert werdenwie geht ihr da so ran? ich denke mal nicht "try end error"
ich suche also ne art liste, die einem anhaltspunkte über den zeitverbrauch von operationen gibt
danke + cu
ps: ich denke zb. dass ein zugriff auf zeichen von zeichenketten direkt über zeiger, statt über operator[] schneller gehen würd, da bei operator[] ja noch ein paar dinge getestet werden!?
udn ähnlich ist das doch bestimmt bei anderen sachen auch!?
-
ich denke zb. dass ein zugriff auf zeichen von zeichenketten direkt über zeiger, statt über operator[] schneller gehen würd, da bei operator[] ja noch ein paar dinge getestet werden!?
Bei char-Arrays wird beim operator[] mit Sicherheit nichts getestet.
-
ERROR schrieb:
wie geht ihr da so ran? ich denke mal nicht "try end error"
ja. und im hintergrund jahrzehntelange erfahrung.
ps: ich denke zb. dass ein zugriff auf zeichen von zeichenketten direkt über zeiger, statt über operator[] schneller gehen würd, da bei operator[] ja noch ein paar dinge getestet werden!?
a[b] ist gleich zu *(a+b).
hast beifor(int i=0;i<100;++i) a[i]=rand();
gegen
for(char* i=a;i<100+a;++i) *i=rand();
folgendes anzunehmen:
- a[i] ist genausoschnell wie *i, wenn sizeof(a[0]) ne kleine zweierotenz ist (siehe adressierungsarten vom intel).
- 100+a wird nicht in der schleife ausgewertet, sondern der compiler macht drausint* end=100+a for(char* i=a;i<end;++i) *i=rand();
also gleich schnell.
aber wie isses mit registern? die version mit a[i] braucht eines für a und eines für i. die andere version braucht eines für i und eines für end. auch gleich.
im optimierungshandbuch für ??? (name vergessen) steht, daß man a[i] vorziehen soll. meine programmierpraxis bestätig das in bezug auf registerverbrauch. a[i] ist oft billiger. wenn ich wpc-gewinner-code angucke, ist mehrheitlich oft die *i-version drin. also nimm für wpc lieber *i.
schau dir immer wieder mal den entstehenden assemblercode an. zur not lerne halt dabei assembler. mußt letztendlich ein gefühl dafür kriegen, welchen assemblercode der compiler draus machen kann.
und miss selber. mit rdtsc und nem guten messprogramm, das auf ein paar takte genau misst. hab meines hier bei irgend einem wpc-thread veröffentlicht.manche sachen sind auch völlig willkürlich, zum beispiel hab ich in wpc112 (gewonnen) ne seltsame referenz eingebaut:
int wpc112(int *start, int *end, int n) { int result=n;//think of n distinct line segments for(int& s=n;--s;){//(s is an other name f³r n) while there are line segments left int t=0;//target starts at 0 do{//and runs till just before n if(end[s]>=start[t]){//if the source ... int start_s=start[s];//(start_s is an other (faster) name for start[s]) if(start_s<=end[t]){//...meets a target --result;//the source will vanish if(start[t]>start_s)//join source and target by updating the target to start[t]=start_s;//the smaller start if(end[t]<end[s])//and the greater end end[t]=end[s]; break;//source vanished by joining with target, we can go to next source } } }while(++t<s); }; return result; }
warum steht da in der äußeren schleife int& i? ich hab keine ahnung, aber dieser griff brachte 2% beschleunigung. und durch keine andere variante mit kopie oder zeiger oder sonstwas kam ich auf was gleichschnelles.