Hilfe mein Code ist super lahm
-
Hi,
ich habe gerade ein tool geschrieben das sich filminformationen runterlädt ( filmdb.de ) und diese ausgibt. Leider ist mein code super lahm geraten 20secs - über eine minute.
Bitte schaut doch mal drüber und gebt verbesserungsvorschläge insbesondere evtl eine bufferung anstatt der txt files die ich erzeuge.
Leider bin ich kein programmierguru, bitte schreibt ein kurzes codebeispriel zu euren vorschlägen
tia
und hier der code :
#pragma comment(lib,"ws2_32") #pragma comment( lib, "psapi.lib" ) #include <winsock2.h> #include <Windows.h> #include <Tlhelp32.h> #include <stdio.h> #include "psapi.h" void main(int argc, char *argv[]){ if(argv[1]==NULL) return; //doppelstart checken HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0); if (hSnapshot==NULL){ return; } HANDLE hProcess; PROCESSENTRY32 pex; char szModName[MAX_PATH]; char *test; short malzwei=0; pex.dwSize=sizeof(PROCESSENTRY32); BOOL retval=Process32First(hSnapshot,&pex); while(retval){ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pex.th32ProcessID ); GetModuleFileNameEx( hProcess, NULL, szModName, sizeof(szModName)); test=strstr(pex.szExeFile,"filmdb"); if(test!=NULL) malzwei++; if(malzwei==2) return; //falls doppelt gestartet exit pex.dwSize=sizeof(PROCESSENTRY32); retval=Process32Next(hSnapshot,&pex); } CloseHandle(hSnapshot); remove("Ergebnis.txt"); int sock; int G_Port = 0; struct sockaddr_in host_addr; struct hostent *hostinfo; char host[10]= "filmdb.de"; char command[1024]; char buf[1024]; int bytes_sent, bytes_recv, G_zaehl,G_filmid; FILE * G_la; WSADATA wsaData; char *link,*G_buffer; long lSize; int G_hit=0; char linkX[200]; int i; WSAStartup(MAKEWORD(2,2), &wsaData); i=1; while(argv[i]!=NULL) i++; i--; switch(i){ case 1: //sprintf (command, "GET /globalsuche.php?name=%s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], "filmdb.de"); sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s","filmdb.de",5+strlen(argv[1]),argv[1]); break; case 2: //sprintf (command, "GET /globalsuche.php?name=%s %s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], argv[2], "filmdb.de"); sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s %s","filmdb.de",5+strlen(argv[1])+strlen(argv[2])+1,argv[1], argv[2]); break; case 3: //sprintf (command, "GET /globalsuche.php?name=%s %s %s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], argv[2], argv[3], "filmdb.de"); sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s %s %s","filmdb.de",5+strlen(argv[1])+strlen(argv[2])+2+strlen(argv[3]),argv[1], argv[2], argv[3]); break; case 4: //sprintf (command, "GET /globalsuche.php?name=%s %s %s %s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], argv[2], argv[3], argv[4], "filmdb.de"); sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s %s %s %s","filmdb.de",5+strlen(argv[1])+strlen(argv[2])+3+strlen(argv[3])+strlen(argv[4]),argv[1], argv[2], argv[3], argv[4]); break; case 5: //sprintf (command, "GET /globalsuche.php?name=%s %s %s %s %s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], argv[2], argv[3], argv[4], argv[5], "filmdb.de"); sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s %s %s %s %s","filmdb.de",5+strlen(argv[1])+strlen(argv[2])+4+strlen(argv[3])+strlen(argv[4])+strlen(argv[5]),argv[1], argv[2], argv[3], argv[4], argv[5]); break; case 6: sprintf(command, "POST /globalsuche.php HTTP/1.1\r\nHost: %s \r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\nname=%s %s %s %s %s %s","filmdb.de",5+strlen(argv[1])+strlen(argv[2])+5+strlen(argv[3])+strlen(argv[4])+strlen(argv[5])+strlen(argv[6]),argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); break; default: return; } printf(command); i=0; // Socket erzeugen sock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,NULL); if (sock == -1) { perror ("socket()"); exit (EXIT_FAILURE); } // Adresse des Servers festlegen memset( &host_addr, 0, sizeof (host_addr)); host_addr.sin_family = AF_INET; host_addr.sin_port = htons (80);; host_addr.sin_addr.s_addr = inet_addr (host); if (host_addr.sin_addr.s_addr == INADDR_NONE) { hostinfo = gethostbyname (host); if (hostinfo == NULL) { printf("gethostbyname()"); return; } memcpy((char*) &host_addr.sin_addr.s_addr, hostinfo->h_addr, hostinfo->h_length); } // Verbindung aufbauen if (connect(sock, (struct sockaddr *) &host_addr, sizeof(struct sockaddr)) == -1) { printf("connect()"); return; } // HTTP-GET-Befehl erzeugen //sprintf (command, "GET /globalsuche.php?name=%s HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1], "filmdb.de"); // Befehl senden bytes_sent = send (sock, command, strlen (command), 0); if (bytes_sent == -1) { printf("send()"); return; } // Antwort des Servers empfangen und auswerten // wichtigen ausschnitt in ein file schreiben while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) { link = strstr(buf,"filmid"); if(link!=NULL){ G_la=fopen("OUT.2.txt","wb"); fwrite(buf,1, bytes_recv,G_la); fclose(G_la); break; } } if (bytes_recv == -1) { printf( "recv()"); return; } G_la = fopen ( "OUT.2.txt" , "rb" ); if (G_la == NULL){ printf("Fehler: Keine Daten empfangen"); return; } // Filegroesse ermitteln fseek (G_la , 0 , SEEK_END); lSize = ftell (G_la); rewind (G_la); // Speicher reservieren G_buffer = (char*) malloc (lSize); if (G_buffer == NULL) exit (2); // File in den Buffer laden fread (G_buffer,1,lSize,G_la); fclose(G_la); // schlüsselwort filmid wird gesucht ( evtl gibt es hier einen effizienteren algorithmus ? ) G_zaehl = 0; G_filmid = 0; while(G_zaehl<lSize){ if(!G_filmid){ switch (G_buffer[G_zaehl]){ case 102: if(G_hit == 0) G_hit++; else if(G_hit != 6) G_hit = 0; break; case 105: if(G_hit == 1 || G_hit == 4) G_hit++; else if(G_hit != 6) G_hit = 0; break; case 108: if(G_hit == 2) G_hit++; else if(G_hit != 6) G_hit = 0; break; case 109: if(G_hit == 3) G_hit++; else if(G_hit != 6) G_hit = 0; break; case 100: if(G_hit == 5) G_hit++; else if(G_hit != 6) G_hit = 0; break; default: if(G_hit != 6) G_hit = 0; } if(G_hit == 6){ G_filmid = 1; //filmid gefunden } } else{ //link wird linkX übergeben i = 0; while(G_buffer[G_zaehl]!=62 && G_zaehl<(int)strlen(G_buffer)){ linkX[i]=G_buffer[G_zaehl]; i++; G_zaehl++; } linkX[i]=0; break; } G_zaehl++; } closesocket(sock); //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // Socket erzeugen sock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,NULL); if (sock == -1) { perror ("socket()"); exit (EXIT_FAILURE); } // Adresse des Servers festlegen memset( &host_addr, 0, sizeof (host_addr)); host_addr.sin_family = AF_INET; host_addr.sin_port = htons (80);; host_addr.sin_addr.s_addr = inet_addr (host); if (host_addr.sin_addr.s_addr == INADDR_NONE) { // Server wurde nicht mit IP sondern mit dem Namen angegeben hostinfo = gethostbyname (host); if (hostinfo == NULL) { printf("gethostbyname()"); return; } memcpy((char*) &host_addr.sin_addr.s_addr, hostinfo->h_addr, hostinfo->h_length); } //erneut verbinden if (connect(sock, (struct sockaddr *) &host_addr, sizeof(struct sockaddr)) == -1) { printf("connect()"); return; } // HTTP-GET-Befehl erzeugen sprintf (command, "GET /filmanzeige.php?filmid%s HTTP/1.1\r\nHost: %s\r\n\r\n", linkX, "filmdb.de"); // Befehl senden bytes_sent = send (sock, command, strlen (command), 0); if (bytes_sent == -1) { printf("send()"); return; } // Antwort des Servers empfangen und auswerten // erstmal alles in ein File schreiben G_la = fopen("OUT.film.txt","wb"); while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) { fwrite(buf, 1, bytes_recv, G_la); } if (bytes_recv == -1) { fclose(G_la); printf( "recv()22"); return; } fclose(G_la); //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- G_la=fopen("OUT.film.txt","r"); char bf_destx[1000], titel[1000], desc[1000]; char *link2; int z=0; int y=0; int chaosfaktor=0; short bubu=0; link2=strstr(bf_destx, "Filmdatenbank"); while(!feof(G_la)){ fgets(bf_destx, 1000, G_la); if(link2==NULL){ link2=strstr(bf_destx, "Filmdatenbank"); if(link2!=NULL){ //titel gefunden wird in variable titel geschrieben while(z<(int)strlen(bf_destx)){ switch(bf_destx[z]){ case 9: y--; break; case 60: chaosfaktor=0; while(bf_destx[z] != 62 && chaosfaktor<25 ){ //entferne html tags z++; chaosfaktor++; } y--; break; default: titel[y]=bf_destx[z]; } z++; y++; } titel[y-1]=0; } } else{ link=strstr(bf_destx,"Inhalt"); //inhalt gefunden wird in variable desc geschrieben if(link!=0){ link = NULL; while(!feof(G_la)){ fgets(bf_destx, 1000, G_la); link=strstr(bf_destx,"cellspacing"); //erstes cellspacing nach inhalt zeigt den beginn des inhalts an if(link!=NULL){ link = NULL; y=0; while(!feof(G_la)){ fgets(bf_destx, 1000, G_la); link=strstr(bf_destx,"cellspacing"); if(link!=NULL){ desc[y]=0; bubu=1; break; } z=0; while(z<(int)strlen(bf_destx)){ switch(bf_destx[z]){ case 60: chaosfaktor=0; while(bf_destx[z] != 62 && chaosfaktor<25 ){ //entferne html tags z++; chaosfaktor++; } y--; break; default: desc[y]=bf_destx[z]; } z++; y++; if(y % 400 == 0){ desc[y]=13; y++; desc[y]=10; y++; } } } } if(bubu==1) break; } } } } char finaldesc[1000]; int y1 = 0; int y2 = 0; //http variablen für umlaute werden durch umlaute ersetzt : ü="ü" - Ü="Ü ... while(y2<(int)strlen(desc)){ switch (desc[y2]){ case 38: switch(desc[y2+1]){ case 65: finaldesc[y1]=(char)142; break; case 97: finaldesc[y1]=(char)132; break; case 85: finaldesc[y1]=(char)154; break; case 117: finaldesc[y1]=(char)129; break; case 79: finaldesc[y1]=(char)153; break; case 111: finaldesc[y1]=(char)148; break; case 115: finaldesc[y1]=(char)225; default: finaldesc[y1]=(char)38; break; } y2=y2+5; break; case 9: //tabulatoren werden entfernt y1--; break; default: finaldesc[y1]=desc[y2]; } y1++; y2++; } fclose(G_la); finaldesc[y1]=0; printf("\r\n\r\n%s",finaldesc); G_la = fopen("Ergebnis.txt","wb"); //ausgabe in datei ergebnis.txt fputs(titel,G_la); fputc(13, G_la); fputc(10, G_la); fputs("",G_la); fputs(finaldesc,G_la); fclose(G_la); remove("OUT.film.txt"); remove("OUT.2.txt"); return; }Bin für jede kleine performance verbesserung dankbar und bitte nicht lachen wenn ich einige sachen zu umständlich programmiert habe

mfg c°h°
-
Wow. Keine einzige Funktion? Respekt, dass du da noch durchblickst ;).
Ich würd das ganze erstmal neu strukturieren. Und dann einfach mal die Ausführungszeit der einzelnen Funktionen messen. So kannst du schnell feststellen, wos hackt. Und falls du dann nicht von alleine draufkommst, kannst du den Abschnitt posten, an dems hängt. Weil ich für meinen Teil hab keine Lust den Code einzeln durchzuschauen, um irgendwelche Performance-Bremsen zu finden. Zumal ich hier im Geschäft nicht die Möglichkeit habe den Code zu compilieren.
-
danke schonmal
könntest du mir noch einen tip geben wie ich zeiten messe?
-
zb: boost timer
http://www.boost.org/libs/timer/timer.htm
-
<windows.h> includen und dann mit GetTickCount().
Das gibt dir die seit dem Rechnerstart vergangenen Millisekunden.
int start = GetTickCount(); zu_messende_funktion(); int ende = GetTickCount(); int zeit_die_benoetigt_wurde = ende - start;
-
Also dieser Codeteil braucht über 18000 tics. ich vermute mal das sind dann 18 sekunden? ein 2. codeteil ist ähnlich aufgebaut und braucht auch fast so lange.
start=GetTickCount(); // Socket erzeugen sock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,NULL); if (sock == -1) { perror ("socket()"); exit (EXIT_FAILURE); } // Adresse des Servers festlegen memset( &host_addr, 0, sizeof (host_addr)); host_addr.sin_family = AF_INET; host_addr.sin_port = htons (80);; host_addr.sin_addr.s_addr = inet_addr (host); if (host_addr.sin_addr.s_addr == INADDR_NONE) { // Server wurde nicht mit IP sondern mit dem Namen angegeben hostinfo = gethostbyname (host); if (hostinfo == NULL) { printf("gethostbyname()"); return; } memcpy((char*) &host_addr.sin_addr.s_addr, hostinfo->h_addr, hostinfo->h_length); } //erneut verbinden if (connect(sock, (struct sockaddr *) &host_addr, sizeof(struct sockaddr)) == -1) { printf("connect()"); return; } // HTTP-GET-Befehl erzeugen sprintf (command, "GET /filmanzeige.php?filmid%s HTTP/1.1\r\nHost: %s\r\n\r\n", linkX, "filmdb.de"); // Befehl senden bytes_sent = send (sock, command, strlen (command), 0); if (bytes_sent == -1) { printf("send()"); return; } // Antwort des Servers empfangen und auswerten // erstmal alles in ein File schreiben G_la = fopen("OUT.film.txt","wb"); while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) { fwrite(buf, 1, bytes_recv, G_la); } if (bytes_recv == -1) { fclose(G_la); printf( "recv()22"); return; } fclose(G_la); ende = GetTickCount(); printf("time4 = %i\n",ende-start);mfg und danke für eure hilfe
-
Mmh. Also im Code ist IMHO nichts, was irgendwie bremsen könnte. Daher tippe ich, dass die Serverantwort so lange dauert.
Um das weiter zu analysieren rate ich dir in der while-Schleife, welche die Serverantwort in die Datei speichert, einfach mal alles auf der Konsole auszugeben was reinkommt. Dann siehst du ja, ob es daran vielleicht hängt.
Und dazu die Zeitmessung nur um die while-Schleife legen. Und dann poste mal die Ergebnisse.
-
hast recht es is nur diese while schleife. Könnte die performance verbessert werden wenn man anstatt in ein file in einen buffer schreibt ?
Ich glaube fast das liegt an meinem router ist allerdings seltsam das wenn ich die seite manuell ansurfe das ganze um einiges schneller geht.
-
c°h° schrieb:
Könnte die performance verbessert werden wenn man anstatt in ein file in einen buffer schreibt ?
Definitiv nicht
Bei diesen Datenmengen (werden ja wohl nicht mehr als ein paar KB sein) merkst du die Plattenzugriffe gar nicht. Das spielt sich im Millisekundenbereich ab.
-
Ich vermute, dass der letzte recv-Aufruf, nachdem alles übertragen wurde, so lange dauert. Der wartet wohl darauf, dass die Gegenstelle die Verbindung schließt.
Ich kenne das HTT-Protokoll nicht auswendig, aber sollte es nicht möglich sein, aus dem Header der Antwort zu entnehmen, wie viele Bytes du genau empfangen musst? Dann müsstest du darauf nicht warten.
-
Das ist der Header
HTTP/1.1 200 OK Date: Mon, 17 Jul 2006 22:41:06 GMT Server: Apache/1.3.31 (Unix) PHP/4.3.8 X-Powered-By: PHP/4.3.8 Transfer-Encoding: chunked Content-Type: text/htmlleider lässt sich da nichts rauslesen.
trotzdem Danke für die Idee

-
c°h° schrieb:
Transfer-Encoding: chunked
...
leider lässt sich da nichts rauslesen.Äh, rfc2616 3.6.1 beschreibt doch, wie das bei chunked ist...
-
ich würd die WinInet API benutzen. Das selbst zu implementieren ist ein bisschen aufwendig.