title: Great Performance Decreasement when Moving the GetDC code into a thread
body: <p>For the next question of <a href="https://stackoverflow.com/questions/66514155/strange-efficiency-decrease-when-localizing-a-global-variable-into-a-subthread">Strange Efficiency Decrease when Localizing a Global Variable into a Subthread</a>, resently I found the question of the performance decreasement is actually caused by moving the GetDC code into a thread, where it was originally placed in a WindowProc/WndProc function, but I have no idea with the detail.</p>
  <p>Could anyone help me?</p>
  <p>After all, here is my code:</p>
  <p>Quick one:</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
  #include &lt;windows.h&gt;
  #define num 4
  #define width 1
  double position[num][2] = {{733, 434}, {633, 384}, {733, 284}, {733, 684}};
  double velocity[num][2] = {{-5, 2.5}, {5, -2.5}, {0, 2.5}, {10, -2.5}};
  COLORREF color[num] = {0xffffff, 0x00ffff, 0x0000ff, 0xffff00};
  COLORREF background_color = 0x000000;
  double distance;
  int count, i, j;
  HDC hdc[num];
  HPEN hpen[num];
  inline double sqr(double x) {return x * x;}
  DWORD WINAPI threadProc(LPVOID lpParamter) {
      Sleep(1000);
      while(1) {
          for(i=0; i&lt;num; ++i) {
              LineTo(hdc[i], position[i][0], position[i][1]);
              position[i][0] += velocity[i][0];
              position[i][1] += velocity[i][1];
          }
      }
  }
  LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR pCmdLine, int nCmdShow) {
      const char *CLASS_NAME = &quot;SUGEWND&quot;;
      void *pHWND = &amp;hInstance;
      WNDCLASS wc = {};
      wc.lpfnWndProc = WindowProc;
      wc.hInstance = hInstance;
      wc.lpszClassName = CLASS_NAME;
      RegisterClass(&amp;wc);
      HWND hwnd = CreateWindowEx(0, CLASS_NAME, &quot;SUGE&quot;, 
      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
      CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
      if(hwnd == NULL) return 0;
      ShowWindow(hwnd, SW_SHOWMAXIMIZED);
      MSG msg={};
      while(GetMessage(&amp;msg, NULL, 0, 0)) {
          TranslateMessage(&amp;msg);
          DispatchMessage(&amp;msg);
      }
      return 0;
  }
  LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
      switch(uMsg) {
          case WM_DESTROY: {
              PostQuitMessage(0);
              return 0;
          }
          case WM_PAINT: {
              PAINTSTRUCT ps;
              HDC hdc2=BeginPaint(hwnd, &amp;ps);
              FillRect(hdc2, &amp;ps.rcPaint, CreateSolidBrush(background_color));
              EndPaint(hwnd, &amp;ps);
              return 0;
          }
          case WM_CREATE: {
              for(i=0; i&lt;num; ++i) {
                  hdc[i] = GetDC(hwnd);
                  hpen[i] = CreatePen(PS_SOLID, width, color[i]);
                  SelectObject(hdc[i], hpen[i]);
                  MoveToEx(hdc[i], position[i][0], position[i][1], 0);
              }
              HANDLE hThread = CreateThread(NULL, 0, threadProc, NULL, 0, NULL);
              CloseHandle(hThread);
              return 0;
          }
      }
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }
  </code></pre>
  <p>Slow one:</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
  #include &lt;windows.h&gt;
  #define num 4
  #define width 1
  double position[num][2] = {{733, 434}, {633, 384}, {733, 284}, {733, 684}};
  double velocity[num][2] = {{-5, 2.5}, {5, -2.5}, {0, 2.5}, {10, -2.5}};
  COLORREF color[num] = {0xffffff, 0x00ffff, 0x0000ff, 0xffff00};
  COLORREF background_color = 0x000000;
  double simulate_acc = 0.00001;
  double distance;
  int count, i, j;
  HDC hdc[num];
  HPEN hpen[num];
  inline double sqr(double x) {return x * x;}
  DWORD WINAPI threadProc(LPVOID lpParamter) {
      HWND hwnd = *(HWND*)lpParamter;
      for(i=0; i&lt;num; ++i) {
          hdc[i] = GetDC(hwnd);
          hpen[i] = CreatePen(PS_SOLID, width, color[i]);
          SelectObject(hdc[i], hpen[i]);
          MoveToEx(hdc[i], position[i][0], position[i][1], 0);
      }
      Sleep(1000);
      while(1) {
          for(i=0; i&lt;num; ++i) {
              LineTo(hdc[i], position[i][0], position[i][1]);
              position[i][0] += velocity[i][0];
              position[i][1] += velocity[i][1];
          }
      }
  }
  LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR pCmdLine, int nCmdShow) {
      const char *CLASS_NAME = &quot;SUGEWND&quot;;
      void *pHWND = &amp;hInstance;
      WNDCLASS wc = {};
      wc.lpfnWndProc = WindowProc;
      wc.hInstance = hInstance;
      wc.lpszClassName = CLASS_NAME;
      RegisterClass(&amp;wc);
      HWND hwnd = CreateWindowEx(0, CLASS_NAME, &quot;SUGE&quot;, 
      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
      CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
      if(hwnd == NULL) return 0;
      ShowWindow(hwnd, SW_SHOWMAXIMIZED);
      MSG msg={};
      while(GetMessage(&amp;msg, NULL, 0, 0)) {
          TranslateMessage(&amp;msg);
          DispatchMessage(&amp;msg);
      }
      return 0;
  }
  LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
      switch(uMsg) {
          case WM_DESTROY: {
              PostQuitMessage(0);
              return 0;
          }
          case WM_PAINT: {
              PAINTSTRUCT ps;
              HDC hdc2=BeginPaint(hwnd, &amp;ps);
              FillRect(hdc2, &amp;ps.rcPaint, CreateSolidBrush(background_color));
              EndPaint(hwnd, &amp;ps);
              return 0;
          }
          case WM_CREATE: {
              HANDLE hThread = CreateThread(NULL, 0, threadProc, &amp;hwnd, 0, NULL);
              CloseHandle(hThread);
              return 0;
          }
      }
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }
  </code></pre>