#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
////////////// MESURE DU TEMPS
 
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
 
DWORD intern_chrono;
 
void ReInitChrono()
{
	intern_chrono = timeGetTime();
}
 
unsigned long GetChrono()
{
	return timeGetTime() - intern_chrono;
}
 
////////////// FIN DE MESURE DU TEMPS
 
int Rien(int a)
{
	return a;
}
 
inline int RienI(int a)
{
	return a;
}
 
struct Chaine
{
	struct Chaine* n;
	int E;
};
 
 
int main()
{
	int i,j;
	int tmp=0;
	float ftmp = 0.0f;
	double dtmp = 0.0;
  double total=0;
	char* p;
 
/****************** OPERATIONS DE BASE *********************/
 
// Test : +=
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp+=i;
	printf("100M += : %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : += et inline fonc
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp+=RienI(i);
	printf("100M += ; 100M appels de fonction inline: %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : += et fonc
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp+=Rien(i);
	printf("100M += ; 100M appels de fonction: %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : *=
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp*=i;
	printf("100M *= : %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : += et +
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp+=i+i;
	printf("100M += et 100M + : %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : += et *
	ReInitChrono();
	for(i=0;i<100000000;i++)
		tmp+=i*i;
	printf("100M += et 100M * : %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : += float
	ReInitChrono();
	for(i=0;i<100000000;i++)
		ftmp+=0.1f;
	printf("100M += float : %d millisecondes\n",GetChrono());
  total+=ftmp;

// Test : += double
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=0.1;
	printf("100M += double : %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += cast float
	ReInitChrono();
	for(i=0;i<100000000;i++)
		ftmp+=(float)i;
	printf("100M += float+cast : %d millisecondes\n",GetChrono());
  total+=ftmp;
 
// Test : += cast double
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=(double)i;
	printf("100M += double+cast : %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += 2cast float, *
	ReInitChrono();
	for(i=0;i<100000000;i++)
		ftmp+=(float)i*(float)i;
	printf("100M += float, 200M cast, 100M * : %d millisecondes\n",GetChrono());
  total+=ftmp;
 
// Test : += 2cast double, *
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=(double)i*(double)i;
	printf("100M += double, 200M cast, 100M * : %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += cast float, *, vtmp
	ReInitChrono();
	float fi;
	for(i=0;i<100000000;i++)
	{
		fi = (float)i;
		ftmp+=fi*fi;
	}
	printf("100M += float, 100M cast, 100M var temp, 100 * : %d millisecondes\n",GetChrono());
  total+=ftmp;
 
// Test : += cast double, *,vtmp
	ReInitChrono();
	double di;
	for(i=0;i<100000000;i++)
	{
		di = (double)i;
		dtmp+=di*di;
	}
	printf("100M += float, 100M cast, 100M var temp, 100 * : %d millisecondes\n",GetChrono());
  total+=dtmp;
 
 
// Test : += cast float&
	ReInitChrono();
	for(i=0;i<100000000;i++)
		ftmp+=(float&)i;
	printf("100M += float+cast& : %d millisecondes\n",GetChrono());
  total+=ftmp;
 
// Test : += cast double&
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=(double&)i;
	printf("100M += double+cast& : %d millisecondes\n",GetChrono());
  total+=dtmp;
 
/************* ALLOCATIONS *****************/
 
// Test : malloc
	ReInitChrono();
	for(i=0;i<1000000;i++)
	{
		p = (char*)malloc(100);
		free(p);
	}
	printf("1M malloc(100), 1M free : %d millisecondes\n",GetChrono());
 
// Test : calloc
	ReInitChrono();
	for(i=0;i<1000000;i++)
	{
		p = (char*)calloc(100,0);
		free(p);
	}
	printf("1M calloc(100,0), 1M free : %d millisecondes\n",GetChrono());
 
// Test : new delete
	ReInitChrono();
	for(i=0;i<1000000;i++)
	{
		p = new char[100];
		delete [] p;
	}
	printf("1M new char[100], 1M delete : %d millisecondes\n",GetChrono());
 
// Test : malloc
	ReInitChrono();
	for(i=0;i<1000;i++)
	{
		p = (char*)malloc(100000);
		free(p);
	}
	printf("1K malloc(100000), 1M free : %d millisecondes\n",GetChrono());
 
// Test : new delete
	ReInitChrono();
	for(i=0;i<1000;i++)
	{
		p = new char[100000];
		delete [] p;
	}
	printf("1K new char[100000], 1M delete : %d millisecondes\n",GetChrono());
 
// Test : malloc avec creation pointeur
	ReInitChrono();
	for(i=0;i<1000000;i++)
	{
		char* p2;
		p2 = (char*)malloc(100);
		free(p2);
	}
	printf("1M malloc(100), 1M free, 1M creation var interne : %d millisecondes\n",GetChrono());
 
/********************** CHAINAGE STRUCTURES ************************/
 
	struct Chaine* S = new struct Chaine;
	struct Chaine* head = S;
	for(i=0;i<1000;i++)
	{
		S->E = i;
		S->n = new struct Chaine;
		S = S->n;
		S->n = NULL;
	}
 
// Test : chainage
	ReInitChrono();
	for(j=0;j<1000000;j++)
	{
		S = head;
		for(i=0;i<100;i++)
		{
			tmp = S->n->n->n->n->n->n->n->n->n->n->E;
			S = S->n;
		}
	}
	printf("100M 10 indirections : %d millisecondes\n",GetChrono());
  total+=tmp;
 
// Test : chainage
	ReInitChrono();
	struct Chaine* Stmp;
	for(j=0;j<1000000;j++)
	{
		S = head;
		for(i=0;i<100;i++)
		{
			Stmp = S->n->n->n->n->n;
			tmp = Stmp->n->n->n->n->n->E;
			S = S->n;
		}
	}
	printf("100M 2*5 indirections : %d millisecondes\n",GetChrono());
  total+=tmp;
 
	S = head;
	while(head!=NULL)
	{
		S = head->n;
		delete head;
		head = S;
	}
 
 
/******************* FONCTIONS MATHEMATIQUES ***********************/
 
// Test : += et sqrt
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=sqrt((double)i);
	printf("100M += et 100M sqrt et 100M cast double: %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += et sin
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=sin((double)i);
	printf("100M += et 100M sin et 100M cast double: %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += et cos
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=cos((double)i);
	printf("100M += et 100M cos et 100M cast double: %d millisecondes\n",GetChrono());
  total+=dtmp;
 
// Test : += et tan
	ReInitChrono();
	for(i=0;i<100000000;i++)
		dtmp+=tan((double)i);
	printf("100M += et 100M tan et 100M cast double: %d millisecondes\n",GetChrono());
  total+=dtmp;
 
 
  printf("%f",total);
	system("pause");
 
	return 0;
}
 
 
/*
 
Mes resultats (Core 2 Duo @ 2.4GHz (E6600)):


AVEC VECTORISATIONS (SSE3, compilo intel) :

100M += : 23 millisecondes
100M += ; 100M appels de fonction inline: 21 millisecondes
100M += ; 100M appels de fonction: 19 millisecondes
100M *= : 125 millisecondes
100M += et 100M + : 19 millisecondes
100M += et 100M * : 135 millisecondes
100M += float : 126 millisecondes
100M += double : 127 millisecondes
100M += float+cast : 21 millisecondes
100M += double+cast : 81 millisecondes
100M += float, 200M cast, 100M * : 32 millisecondes
100M += double, 200M cast, 100M * : 68 millisecondes
100M += float, 100M cast, 100M var temp, 100 * : 32 millisecondes
100M += float, 100M cast, 100M var temp, 100 * : 70 millisecondes
100M += float+cast& : 15 millisecondes
100M += double+cast& : 32 millisecondes
1M malloc(100), 1M free : 5422 millisecondes
1M calloc(100,0), 1M free : 5552 millisecondes
1M new char[100], 1M delete : 5434 millisecondes
1K malloc(100000), 1M free : 107 millisecondes
1K new char[100000], 1M delete : 88 millisecondes
1M malloc(100), 1M free, 1M creation var interne : 5463 millisecondes
100M 10 indirections : 473 millisecondes
100M 2*5 indirections : 477 millisecondes
100M += et 100M sqrt et 100M cast double: 1203 millisecondes
100M += et 100M sin et 100M cast double: 1956 millisecondes
100M += et 100M cos et 100M cast double: 2041 millisecondes
100M += et 100M tan et 100M cast double: 2100 millisecondes
Press any key to continue . . .


Sans vectorisation (moindre en tout cas)(FPU + SSE2, compilo MS) :

100M += : 73 millisecondes
100M += ; 100M appels de fonction inline: 72 millisecondes
100M += ; 100M appels de fonction: 72 millisecondes
100M *= : 126 millisecondes
100M += et 100M + : 74 millisecondes
100M += et 100M * : 129 millisecondes
100M += float : 379 millisecondes
100M += double : 125 millisecondes
100M += float+cast : 461 millisecondes
100M += double+cast : 251 millisecondes
100M += float, 200M cast, 100M * : 503 millisecondes
100M += double, 200M cast, 100M * : 258 millisecondes
100M += float, 100M cast, 100M var temp, 100 * : 502 millisecondes
100M += float, 100M cast, 100M var temp, 100 * : 256 millisecondes
100M += float+cast& : 801 millisecondes
100M += double+cast& : 460 millisecondes
1M malloc(100), 1M free : 5385 millisecondes
1M calloc(100,0), 1M free : 5492 millisecondes
1M new char[100], 1M delete : 5440 millisecondes
1K malloc(100000), 1M free : 106 millisecondes
1K new char[100000], 1M delete : 88 millisecondes
1M malloc(100), 1M free, 1M creation var interne : 5464 millisecondes
100M 10 indirections : 492 millisecondes
100M 2*5 indirections : 493 millisecondes
100M += et 100M sqrt et 100M cast double: 2676 millisecondes
100M += et 100M sin et 100M cast double: 6742 millisecondes
100M += et 100M cos et 100M cast double: 6945 millisecondes
100M += et 100M tan et 100M cast double: 8898 millisecondes
Press any key to continue . . .
 
*/