Du speed pour ultoa() et itoa() (win32, vc++, asm)

Description

Ces 2 fonctions, comme chacun le sait, mettent une
valeur 32 bits en format texte dans un char[].
char* ultoa(value, *szbuff, base);
Elle renvoie un pointeur que l'on a déjà, stupide.
Sera mieux d'obtenir ptr sur zéro final qui permettra
un chainage continu sans se servir de strcat().
Mes 2 funcs le font et sont +- 45% plus véloces que
les originales. Programme de test fourni.
Code complet dans le zip.

Source / Exemple :


#include <windows.h>
#include "FncAsm.h"

#define BNU_INIT   (WM_USER+1)

unsigned __int64 clib, bnlib;
HWND hwndapp = 0;
char szbuff[160];
char *szappname = "OptimiC";
char *szinfo = "Appuyer sur ENTER.\nNe plus toucher le PC.\n"
               "Patienter quelques secondes.\nLes comptes s'afficheront.";

void TestC()
{
  DWORD i, hi, lo;
  __asm {
    rdtsc
    mov     hi, edx
    mov     lo, eax
  }
  for(i = 10000000; i >= 100000; i--) ultoa(i, szbuff, 10);
  __asm {
    rdtsc
    sub     eax, lo
    sbb     edx, hi
    mov     dword ptr clib, eax
    mov     dword ptr clib+4, edx
  }
}

void TestBnc()
{
  DWORD i, hi, lo;
  __asm {
    rdtsc
    mov     hi, edx
    mov     lo, eax
  }
  for(i = 10000000; i >= 100000; i--) bnultoa(i, szbuff);
  __asm {
    rdtsc
    sub     eax, lo
    sbb     edx, hi
    mov     dword ptr bnlib, eax
    mov     dword ptr bnlib+4, edx
  }
}

void dispResult()
{
  char *c;
  c = szbuff+4;
  strcpy(szbuff, "C\t=\t");
  _ui64toa(clib, c, 10);
  while(*c) c++;
  strcpy(c, "\nASM\t=\t"); c += 7;
  _ui64toa(bnlib, c, 10);
  while(*c) c++;
  clib -= bnlib;
  strcpy(c, "\n\ngain\t=\t");
  _ui64toa(clib, c+9, 10);
  MessageBox(hwndapp, szbuff, szappname, MB_ICONINFORMATION);
}

LRESULT CALLBACK AppWndProc(HWND hwnd, UINT mssg, WPARAM wParam, LPARAM lParam)
{
  switch(mssg) {
    case BNU_INIT:
      MessageBox(hwnd, szinfo, szappname, MB_ICONINFORMATION);
      SetCursor(0);
      TestC();
      TestBnc();
      dispResult();
      PostQuitMessage(0);
      return 0;
    case WM_SIZE:
      PostMessage(hwnd, BNU_INIT, 0, 0);
      return 0;
    case WM_SETCURSOR:
      
      return 0;
  }
  return DefWindowProc(hwnd, mssg, wParam, lParam);
}

void __stdcall InitInstance(HINSTANCE hinst)
{
  WNDCLASS     wndcls;
  memset(&wndcls, 0, sizeof(WNDCLASS));
  wndcls.style         = CS_HREDRAW | CS_VREDRAW;
  wndcls.lpfnWndProc   = AppWndProc;
  wndcls.hInstance     = hinst;
  wndcls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
  wndcls.lpszClassName = szappname;
  if(!RegisterClass(&wndcls)) return;
  hwndapp = CreateWindowEx(WS_EX_TOPMOST,
            szappname, "", WS_POPUP | WS_VISIBLE,
            0, 0,
            GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
            0, 0, hinst, 0);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
{
  MSG msg;
  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  InitInstance(hInstance);
  if(hwndapp == NULL) goto appEnd;
  ShowWindow(hwndapp, SW_SHOW); UpdateWindow(hwndapp);
  while(GetMessage(&msg, 0, 0, 0)) {
    TranslateMessage(&msg); DispatchMessage(&msg);
  }
appEnd:
  return 0;
}

Conclusion :


Je n'ai illustré que bnultoa() mais bnitoa est aussi
dans FncAsm.cpp. Elles ne font bien entendu que de
la base 10, le plus courant. Pour sortir en hexa
c'est encore plus simple, en cadeau une prochaine fois.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.