Merwürdiges Verhalten eines Programms.
-
Ich hab ein Programm geschrieben, das mit der GDI und mit PeekMessage etc. ein Bild auf dem Bildschirm darstellt. Dazu hab ich noch mitnotiert, wieviele Bildaktualisierungen er jeweils pro Sekunde schafft. Dieser Wert liegt ziemlich konstant bei 65. Aber jetzt kommt's: Wenn ich mich in Web.de einlogge, springt der Zähler plötzlich hoch auf rund 500. Eigentlich haben der Firefox und dieses Programm doch gar nichts miteinander zu tun. Wie kommt es, daß sich die Performance des Programms schlagartig verbessert, sobald ich eine bestimmte Webseite auf habe?
#include <sstream> #include <windows.h> #include "Resource.h" using namespace std; LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LPCTSTR lpszAppName = TEXT("AppName"); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int iCmdShow) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszClassName = lpszAppName; wc.lpszMenuName = lpszAppName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wc); HWND hWnd = CreateWindowEx( 0, lpszAppName, TEXT("Testprogramm"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); HBITMAP image = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_IMAGE)); MSG msg; ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); clock_t start; int n = 0; start = clock(); do { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message != WM_QUIT) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { HDC dc = GetDC(hWnd); HDC imageDc = CreateCompatibleDC(dc); SelectObject(imageDc, image); BITMAP bm; GetObject(image, sizeof(bm), &bm); BitBlt(dc, 0, 0, bm.bmWidth, bm.bmHeight, imageDc, 0, 0, SRCCOPY); DeleteDC(imageDc); ReleaseDC(hWnd, dc); n++; if ((clock() - start) / CLOCKS_PER_SEC >= 1) { stringstream stream; stream << n << " Bilder pro Sekunde"; SetWindowTextA(hWnd, stream.str().c_str()); n = 0; } Sleep(1); if (n == 0) start = clock(); } } while (msg.message != WM_QUIT); DeleteObject(image); return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; }
-
Puh, vielleicht liegts an den Timern.
Nimm mal Sleep() komplett raus und ersetze clock() durch GetTickCount() und dann durch timeGetTime() und beobachte.
-
Als erstes hab ich jetzt rausgefunden, daß das ganze Grafikzeug überflüssig ist. Der folgende Code reicht völlig aus:
#include <iostream> #include <windows.h> using namespace std; int main() { int i = 0, n = 0; clock_t start = clock(); while (i < 10) { n++; if ((clock() - start) / CLOCKS_PER_SEC >= 1) { cout << n << " Bilder pro Sekunde" << endl; n = 0; i++; } Sleep(1); if (n == 0) start = clock(); } }Mit Sleep haben wir ohne geöffnetes Web.de 65 Durchläufe pro Sekunde und mit Web.de 512. Ohne Sleep scheint's keinen Unterschied zu geben:
Ohne Web.de:
33326397
33331113
33071002
33772951
33722630Mit Web.de:
32416119
33323508
33783168
33536504
33455707Schlauer bin ich jetzt auch nicht: Bei Sleep haben wir den minimalsten Wert und trotzdem ist das Intervall mit geöffnetem Web.de circa achtmal schneller. Aber Sleep wird nicht ganz übersprungen, denn in so einem Fall hätten wir ja Werte im 30 Millionen-Bereich und nicht nur 512. Was vor allem verwundert, ist, daß nicht eine bestimmte Anwendung, wie zum Beispiel der Firefox, sondern eine einzelne Webseite im Firefox die Änderungen bewirkt.
-
Das kann ich mir auch nicht erklären.
Ich könnt mir nur denken, dass web.de irgendein javascript laufen lässt, welches an der timer precision rumspielt.Schreib mal anstatt nur Sleep(1) Folgendes:
timeBeginPeriod(1); Sleep(1); timeEndPeriod(1);Dann sollte es keinen Unterschied mehr geben.
-
Benutz einfach eine richtigen Timer -> SetTimer()