Tests de rapidité (sprintf, fopen...) [dev-c++]

Description

Bon, ce prog ne sert pas a grand chose si ce n'est qu'a prouver que certaines fonctions sont a éviter (et que beaucoup utilisent quand même)

Pas mal de personnes sur ce site critique les fonctions genre sprintf, wsprintf, fopen, fwrite pour des raisons de performances, j'ai juste voulu vérifié !

Je vous préviens, j'ai fait ce code assez rapidemment, et il se peut que mes tests ne sont pas très exacts (bien que ca m'étonnerait)
Cependant, je dois avouer qu'ils m'ont assez étonner, je ne croyais pas tro au fait qu'une succession de strcat et otr était plus rapide qu'un sprintf, j'ai eu tord...
De plus, certains dise que les flux de fichier sont moins performant que le win32, moi j'ai trouver le contraire (bizarre...)

Si quelqu'un croit que je me trompe, qu'il n'hésite pas a le dire !

Source / Exemple :


#include <windows.h>
#include <time.h>
#include <stdio.h>

// Variables globales
char test[256];
int i;
clock_t avant, apres, duree1, duree2;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevInstance, LPSTR CmdLine, int CmdShow)
{    
	/////////////////////////TEST 1 : vitesse de sprintf////////////////////////
	/* sprintf sert à manipuler les chaines de caractères très facilement, mais
	elle est réputer pour être extremement lente !! 
	Dans ce test, je place 1000000 fois une phrase (la même a chaque fois) dans 
	un buffer avec sprintf puis avec strcpy, strcat et autres */

	// Variables utilisés	
	int test2=666666;
	char *test3="blablablabla";

	// méthode 1 : avec sprintf
	avant = clock();
	for(i=0; i<1000000; i++)
		sprintf(test, "%s blablablabla %d blablablabla !!", test3, test2); // Une seul ligne suffit...

	apres = clock();
	duree1 = apres-avant;
	sprintf(test, "Méthode 1 (avec sprintf) : %d", duree1);
	MessageBox(NULL, test, "Vitesse de sprintf", MB_ICONERROR | MB_OK);

	// méthode 2 : sans sprintf
	avant = clock();
	for(i=0; i<1000000; i++)
	{
		/* Pour arriver au même résultat, c'est quand même moins pratique !
		De plus, on peut sans doute encore l'optimiser en se servant de 
		pointeur, mé la, g la flème... */

		strcpy(test, test3);
		strcat(test, " blablablabla ");
		char test4[16]; _ultoa(test2, test4, 10);
		strcat(test, test4);
		strcat(test, " blablablabla !!");
	}
	apres = clock();
	duree2 = apres-avant;
	if(duree1>duree2) sprintf(test, "Méthode 2 (sans sprintf) : %d\n\nRESULTATS : méthode 2 est environ %d fois plus rapide !", duree2, duree1/duree2);
	else sprintf(test, "Méthode 2 (sans sprintf) : %d\n\nRESULTATS : méthode 1 est environ %d fois plus rapide !", duree2, duree2/duree1); 
	MessageBox(NULL, test, "Vitesse de sprintf", MB_ICONERROR | MB_OK);
	////////////////////////////////////////////////////////////////////////////
	//
	// RESULTATS : la méthode sans sprintf est 3 fois plus rapide chez moi
	//
	// /!\ cependant, en faisant le test avec wsprintf, on remarque que cette
	// fonction est tt de même plus rapide que sprintf
	//
	//////////////////////////////////////////////////////////////////////////// 

	/////////////////////////TEST 2 : flux ou win32 ????////////////////////////
	/* fopen comme CreateFile servent à manipuler un fichier du disque dur et à
	écrire dedans avec fwrite ou WriteFile.
	fopen est réputer comme plus lent (de plus il fait appelle a une dll genre 
	msvcrt.dll ou un truc ds le genre) 
	Dans ce test, j'ouvre un fichier en écriture et j'écris 1000000 fois la 
	même phrase. Ensuite, je ferme et efface le fichier.*/

	// méthode 1 : avec flux (fopen, fwrite, fclose)
	avant = clock();
	FILE *ouvre;
	ouvre = fopen("c:\\test.txt", "w");
	for(i=0; i<1000000; i++)		
		fwrite("bla", strlen("bla"), 1, ouvre); 

	if(ouvre!=NULL) fclose(ouvre);
	apres = clock();
	duree1 = apres-avant;
	sprintf(test, "Méthode 1 (avec fopen) : %d", duree1);
	MessageBox(NULL, test, "Flux ou Win32 ?", MB_ICONERROR | MB_OK);
	DeleteFile("c:\\test.txt");

	// méthode 2 : en win32 (CreateFile, WriteFile, CloseHandle)
	avant = clock();
	HANDLE hdl;
	hdl=CreateFile("c:\\test.txt",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
	DWORD dw;
	for(i=0; i<1000000; i++)				
		WriteFile(hdl, "bla", strlen("bla"), &dw, 0 );	  

	CloseHandle(hdl);
	apres = clock();
	duree2 = apres-avant;
	if(duree1>duree2) sprintf(test, "Méthode 2 (avec CreateFile) : %d\n\nRESULTATS : méthode 2 est environ %d fois plus rapide !", duree2, duree1/duree2);
	else sprintf(test, "Méthode 2 (avec CreateFile) : %d\n\nRESULTATS : méthode 1 est environ %d fois plus rapide !", duree2, duree2/duree1);
	MessageBox(NULL, test, "Flux ou Win32 ?", MB_ICONERROR | MB_OK);
	DeleteFile("c:\\test.txt");
	////////////////////////////////////////////////////////////////////////////
	//
	// RESULTATS : la méthode avec flux est 4 a 6 fois plus rapide chez moi,
	// contrairement à ce que je pensais au début...
	//
	////////////////////////////////////////////////////////////////////////////

	return 0;
}

Conclusion :


En définitive, éviter les sprintf et choisissez plutot la méthode 2 (ou au pire wsprintf qui semble un peu plus rapide), surtt dans une boucle !!
Pareil pour l'écriture de fichier, utilisé de préférence fopen et co qui semble bien plus rapide pour l'écriture de gros fichier ! (cependant, je préfère avoir l'avis d'autres personnes la dessus avant d'en être certains)

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.