C++ version See stopwatch
C++, SECURESCL 0, vector of function pointers, __fastcall
//#define FCALLTYPE
//#define FCALLTYPESTR "__cdecl"
#define FCALLTYPE __fastcall
#define FCALLTYPESTR "__fastcall"
typedef void (FCALLTYPE *SumPF)(int &);
void FCALLTYPE OddSum(int &s) { s += 1; }
void FCALLTYPE EvenSum(int &s) { s += 2; }
int main()
{
using namespace std;
vector<SumPF> v;
v.push_back(&OddSum);
v.push_back(&EvenSum);
Stopwatch sw;
sw.Start();
int sum = 0;
const int maxit = 100000000;
for (int i = 0; i < maxit; ++i)
{
vector<SumPF>::iterator it = v.begin();
for (; it != v.end(); ++it)
{
(*it)(sum);
}
}
sw.Stop();
cout << "/**C++, _SECURE_SCL 0, vector of function pointers, " << FCALLTYPESTR << "*/" << endl;
cout << "iterations =" << maxit << endl;
cout << "sum =" << sum << endl;
cout << "Elapsed =" << sw << endl;
cout << "Average =" << sw.GetElapsedMilliseconds() / double(maxit) << " milliseconds/call";
cin.get();
}
C++, SECURESCL 0, direct base class call
#define FCALLTYPE
#define FCALLTYPESTR "__cdecl"
//#define FCALLTYPE __fastcall
//#define FCALLTYPESTR "__fastcall"
struct Base {
virtual void FCALLTYPE Sum(int &s) = 0;
virtual ~Base(){}
};
struct Odd : public Base {
void FCALLTYPE Sum(int &s) { s += 1; }
};
struct Even : public Base {
void FCALLTYPE Sum(int &s) { s += 2; }
};
int main()
{
using namespace std;
Base* podd(new Odd());
Base* peven(new Even());
Stopwatch sw;
sw.Start();
int sum = 0;
const int maxit = 100000000;
for (int i = 0; i < maxit; ++i)
{
podd->Sum(sum);
peven->Sum(sum);
}
sw.Stop();
cout << "/**C++, _SECURE_SCL 0, direct base class call, " << FCALLTYPESTR << "*/" << endl;
cout << "iterations =" << maxit << endl;
cout << "sum =" << sum << endl;
cout << "Elapsed =" << sw << endl;
cout << "Average =" << sw.GetElapsedMilliseconds() / double(maxit) << " milliseconds/call";
cin.get();
delete podd;
delete peven;
}
C++, SECURESCL 0, vector base class call
//#define FCALLTYPE
//#define FCALLTYPESTR "__cdecl"
#define FCALLTYPE __fastcall
#define FCALLTYPESTR "__fastcall"
struct Base {
virtual void FCALLTYPE Sum(int &s) = 0;
virtual ~Base(){}
};
struct Odd : public Base {
void FCALLTYPE Sum(int &s) { s += 1; }
};
struct Even : public Base {
void FCALLTYPE Sum(int &s) { s += 2; }
};
int main()
{
using namespace std;
vector<Base*> v;
v.push_back(new Odd());
v.push_back(new Even());
Stopwatch sw;
sw.Start();
int sum = 0;
const int maxit = 100000000;
for (int i = 0; i < maxit; ++i)
{
vector<Base*>::iterator it = v.begin();
for (; it != v.end(); ++it)
{
(*it)->Sum(sum);
}
}
sw.Stop();
cout << "/**C++, _SECURE_SCL 0, vector base class call, " << FCALLTYPESTR << "*/" << endl;
cout << "iterations =" << maxit << endl;
cout << "sum =" << sum << endl;
cout << "Elapsed =" << sw << endl;
cout << "Average =" << sw.GetElapsedMilliseconds() / double(maxit) << " milliseconds/call";
for (vector<Base*>::iterator it = v.begin(); it != v.end(); ++it)
{
delete *it;
}
cin.get();
}
C# base call
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication1
{
abstract class Base
{
public abstract void Sum(ref int s);
};
class Odd : Base
{
public override void Sum(ref int s) { s += 1; }
};
class Even : Base
{
public override void Sum(ref int s) { s += 2; }
};
class Program
{
static void Main(string[] args)
{
List<Base> list = new List<Base>();
list.Add(new Odd());
list.Add(new Even());
Stopwatch sw = new Stopwatch();
sw.Start();
int sum = 0;
const int maxit = 100000000;
for (int i = 0; i < maxit; ++i)
{
for (int k = 0; k < list.Count; k++)
{
list[k].Sum(ref sum);
}
}
sw.Stop();
Console.WriteLine("iterations : {0}", maxit);
Console.WriteLine("sum : {0}", sum);
Console.WriteLine("Elapsed : {0}", sw.ElapsedMilliseconds);
Console.WriteLine("Average : {0}", sw.ElapsedMilliseconds / (double)maxit);
Console.Read();
}
}
}
C# list ```cpp
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics;
namespace ConsoleApplication1 {
abstract class Base
{
public abstract void Sum(ref int s);
};
class Odd : Base
{
public override void Sum(ref int s) { s += 1; }
};
class Even : Base
{
public override void Sum(ref int s) { s += 2; }
};
class Program
{
static void Main(string[] args)
{
Base odd = new Odd();
Base even = new Even();
Stopwatch sw = new Stopwatch();
sw.Start();
int sum = 0;
const int maxit = 100000000;
for (int i = 0; i < maxit; ++i)
{
odd.Sum(ref sum);
even.Sum(ref sum);
}
sw.Stop();
Console.WriteLine("iterations : {0}", maxit);
Console.WriteLine("sum : {0}", sum);
Console.WriteLine("Elapsed : {0}", sw.ElapsedMilliseconds);
Console.WriteLine("Average : {0}", sw.ElapsedMilliseconds / (double)maxit);
Console.Read();
}
}
} ```
C++, SECURESCL 0, direct base class call, __cdecl
iterations =100000000
sum =300000000
Elapsed =1695 ms (stopped)
Average =1.695e-005 milliseconds/call
C++, SECURESCL 0, direct base class call, __fastcall
iterations =100000000
sum =300000000
Elapsed =769 ms (stopped)
Average =7.69e-006 milliseconds/call
C++, SECURESCL 0, vector of function pointers, __cdecl
iterations =100000000
sum =300000000
Elapsed =2653 ms (stopped)
Average =2.653e-005 milliseconds/call
C++, SECURESCL 0, vector of function pointers, __fastcall
iterations =100000000
sum =300000000
Elapsed =2549 ms (stopped)
Average =2.549e-005 milliseconds/call
C++, SECURESCL 0, vector base class call, __cdecl
iterations =100000000
sum =300000000
Elapsed =3424 ms (stopped)
Average =3.424e-005 milliseconds/call
C++, SECURESCL 0, vector base class call, __fastcall
iterations =100000000
sum =300000000
Elapsed =3320 ms (stopped)
Average =3.32e-005 milliseconds/call
C++, SECURESCL 0, vector base class call, __fastcall, __fastcall in project config
iterations =100000000
sum =300000000
Elapsed =3078 ms (stopped)
Average =3.078e-005 milliseconds/call
C# base call
iterations : 100000000
sum : 300000000
Elapsed : 984
Average : 9,84E-06
C# list
iterations : 100000000
sum : 300000000
Elapsed : 3293
Average : 3,293E-05
Brief
```
C++ vector function ptr 2549
C++ vector 3078
C# list 3293 ~ +6%
C++ base call 769 c# base call 984 ~ +27% ```
Thanks Felipe Farion to point out the use of __fastcall VC++ 2008, uses __cdecl by default.