Le style de programmation par interfaces est séduisant dans certains cas, mais est-il aussi rapide qu'une programmation classique.
Après avoir réfléchi à une approche de test, comment trouver un jeu d'essai simple permettant de comparer ce qui est comparable ? j'ai produit ce petit bout pour vérifier les choses.
A faire tourner, pour ceux que ça intéresse, avec le debug off, sinon attention les temps d'exécutions et les résultats non significatifs.
Le principe de ce test consiste à effectuer une addition de trois entiers. On effectue cette opération de différentes manières, à commencer par une addition directe sans appel de procédure, à titre de comparaison.
L'interface que Heis a écrit est assez simple, et offre un petit avantage par rapport à celui de la doc, c'est qu'il fonctionne tout de suite.
Code : Tout sélectionner
Interface Class
ClassInit(Val1.l, Val2.l, Val3.l)
ClassAdd()
ClassFree()
EndInterface
Structure Class_Functions
ClassInit.l
ClassAdd.l
ClassFree.l
EndStructure
Structure Class_Vars
*VirtualTable.Class_Functions
Val1.l
Val2.l
Val3.l
EndStructure
Procedure ClassAdd(*this.Class_Vars)
ProcedureReturn *this\Val1 + *this\Val2 + *this\Val3
EndProcedure
Structure Class_Holder
VT.Class_Functions
Impl.Class_Vars
EndStructure
NewList Instances.Class_Holder()
Procedure AtomAdd_by_val(x, y, z)
ProcedureReturn x + y + z
EndProcedure
Procedure AtomAdd_by_ref(*x, *y, *z)
! MOV esi, dword [esp]
! MOV eax, [esi]
! ADD eax, [esi+4]
! ADD eax, [esi+8]
ProcedureReturn
EndProcedure
Procedure ClassFree(*this.Class_Vars)
*this\Val1 = 0
*this\Val2 = 0
*this\Val3 = 0
DeleteElement(Instances())
EndProcedure
Procedure ClassInit(Val1.l, Val2.l, Val3.l)
AddElement(Instances())
Instances()\VT\ClassAdd = @ClassAdd()
Instances()\VT\ClassFree = @ClassFree()
Instances()\Impl\VirtualTable = Instances()\VT
Instances()\Impl\Val1 = Val1
Instances()\Impl\Val2 = Val2
Instances()\Impl\Val3 = Val3
ProcedureReturn @Instances()\Impl
EndProcedure
First.Class = ClassInit(1, 2, 3)
Second.Class = ClassInit(4, 5, 6)
NTimes = 100000000
a = 1
b = 2
c = 3
d = 4
e = 5
f = 6
*a = @a
*b = @b
*c = @c
*d = @d
*e = @e
*f = @f
Titre.s = "Addition directe de trois entiers dans le code principal"
tz = ElapsedMilliseconds()
For i = 1 To NTimes
iFirst.l = a + b + c
iSecond.l = d + e + f
Next
tz = ElapsedMilliseconds() - tz
Result.s = Titre + Chr(10) + "First : " + Str(iFirst) + " Second : " + Str(iSecond) + " Done in " + Str(tz) + "ms" + Chr(10)
Titre.s = "Addition de trois entiers par appel de procédure classique avec transmission par valeurs"
tz = ElapsedMilliseconds()
For i = 1 To NTimes
iFirst.l = AtomAdd_by_val(a, b, c)
iSecond.l = AtomAdd_by_val(d, e, f)
Next
tz = ElapsedMilliseconds() - tz
Result + Titre + Chr(10) + "First : " + Str(iFirst) + " Second : " + Str(iSecond) + " Done in " + Str(tz) + "ms" + Chr(10)
Titre.s = "Addition de trois entiers par appel de procédure classique avec transmission par adresses"
tz = ElapsedMilliseconds()
For i = 1 To NTimes
iFirst.l = AtomAdd_by_ref(@a, @b, @c)
iSecond.l = AtomAdd_by_ref(@d, @e, @f)
Next
tz = ElapsedMilliseconds() - tz
Result + Titre + Chr(10) + "First : " + Str(iFirst) + " Second : " + Str(iSecond) + " Done in " + Str(tz) + "ms" + Chr(10)
Titre.s = "Addition de trois entiers par appel de procédure classique avec transmission par pointeurs"
tz = ElapsedMilliseconds()
For i = 1 To NTimes
iFirst.l = AtomAdd_by_ref(*a, *b, *c)
iSecond.l = AtomAdd_by_ref(*d, *e, *f)
Next
tz = ElapsedMilliseconds() - tz
Result + Titre + Chr(10) + "First : " + Str(iFirst) + " Second : " + Str(iSecond) + " Done in " + Str(tz) + "ms" + Chr(10)
Titre.s = "Addition de trois entiers par appel de procédure par interface"
tz = ElapsedMilliseconds()
For i = 1 To NTimes
iFirst.l = First\ClassAdd()
iSecond.l = Second\ClassAdd()
Next
tz = ElapsedMilliseconds() - tz
Result + Titre + Chr(10) + "First : " + Str(iFirst) + " Second : " + Str(iSecond) + " Done in " + Str(tz) + "ms" + Chr(10)
MessageRequester("Result", Result, #PB_MessageRequester_Ok)
First\ClassFree()
Second\ClassFree()
End