Page 1 sur 3
INT : Fonction trop lente
Publié : mar. 26/mai/2009 19:27
par Le Soldat Inconnu
Salut,
voilà un simple comparatif de vitesse qui est à mon avis assez évoquant
D'un coté : INT
De l'autre : Un code tout simple 16 fois plus rapide que INT chez moi, simplement mettre le float - 0.5 dans un long
le test
Code : Tout sélectionner
Float1.f = 5.958741545
Float2.f = 6.12154872534
#Nb = 50000000
Time1 = ElapsedMilliseconds()
For i = 1 To #Nb
Long11.l = Int(Float1)
Long12.l = Int(Float2)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To #Nb
Long21.l = Float1 - 0.5
Long22.l = Float2 - 0.5
Next
Time3 = ElapsedMilliseconds()
Texte.s = "Int :" + Chr(10) + "Time = " + Str(Time2 - Time1) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long11) + Chr(10) + StrF(Float2) + " -> " + StrF(Long12) + Chr(10) + Chr(10) + "Float - 0.5 to Long :" + Chr(10) + "Time = " + Str(Time3 - Time2) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long21) + Chr(10) + StrF(Float2) + " -> " + StrF(Long22) + Chr(10) + StrF((Time2 - Time1) / (Time3 - Time2), 1) + " time more fast"
SetClipboardText(Texte)
MessageRequester("Test", Texte)
résultat
Int :
Time = 2235 ms
5.958742 -> 5.000000
7.125487 -> 7.000000
Float - 0.5 to Long :
Time = 140 ms
5.958742 -> 5.000000
7.125487 -> 7.000000
16.0 time more fast
et chez vous ?
Publié : mar. 26/mai/2009 19:39
par Atomo
J'obtient ce résultat avec le débugger off :
Int :
Time = 686 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
Float - 0.5 to Long :
Time = 110 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
6.2 time more fast
Publié : mer. 27/mai/2009 7:59
par kelebrindae
---------------------------
Test
---------------------------
Int :
Time = 3859 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
Float - 0.5 to Long :
Time = 203 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
19.0 time more fast
Impressionnant !
Une question (bête, sans doute): à quoi sert le "-0.5" ?
Publié : mer. 27/mai/2009 8:37
par cha0s
sous mon nux :
Int :
Time = 4259 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
Float - 0.5 to Long :
Time = 324 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
13.1 time more fast
Publié : mer. 27/mai/2009 9:05
par Good07
Sur mon IMac intel core 2 duo 2,4 ghz 2 GO de ram
Pure Basic 4.31 Béta 1
Avec debogueur en service:
Int :
Time = 8604 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
Float - 0.5 to Long :
Time = 7628 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
1.1 time more fast
Sans debogueur:
Int :
Time = 316 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
Float - 0.5 to Long :
Time = 145 ms
5.958742 -> 5.000000
6.121549 -> 6.000000
2.2 time more fast
Il semble que le debogueur patauge dans la choucroute...

Publié : mer. 27/mai/2009 10:05
par Le Soldat Inconnu
ma première solution n'est pas la meilleure, elle ne marche pas à tous les coups
voici une version meilleure, qui reste 2 fois plus rapide
Code : Tout sélectionner
Procedure MyInt(Float.f)
Protected Long.l
Long = Float
If Float > 0
If Float < Long
Long - 1
EndIf
Else
If Float > Long
Long + 1
EndIf
EndIf
ProcedureReturn Long
EndProcedure
Float1.f = 5.958741545
Float2.f = 5
#Nb = 50000000
Time1 = ElapsedMilliseconds()
For i = 1 To #Nb
Long11.l = Int(Float1)
Long12.l = Int(Float2)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To #Nb
Long21.l = MyInt(Float1)
Long22.l = MyInt(Float2)
Next
Time3 = ElapsedMilliseconds()
Texte.s = "Int :" + Chr(10) + "Time = " + Str(Time2 - Time1) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long11) + Chr(10) + StrF(Float2) + " -> " + StrF(Long12) + Chr(10) + Chr(10) + "Float - 0.5 to Long :" + Chr(10) + "Time = " + Str(Time3 - Time2) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long21) + Chr(10) + StrF(Float2) + " -> " + StrF(Long22) + Chr(10) + StrF((Time2 - Time1) / (Time3 - Time2), 1) + " time more fast"
SetClipboardText(Texte)
MessageRequester("Test", Texte)
Publié : mer. 27/mai/2009 10:53
par lionel_om
Le truc de ton code d'avant c'est que y'avait pas d'appel à une fonction. Donc pas d'utilisation de la pile, etc...
Essaye juste ça: (même code que toi, mais le calcul est fait dans une fonction).
Code : Tout sélectionner
Float1.f = 5.958741545
Float2.f = 6.12154872534
#Nb = 50000000
Procedure.l Test(Float.f)
ProcedureReturn Float - 0.5
EndProcedure
Time1 = ElapsedMilliseconds()
For i = 1 To #Nb
Long11.l = Int(Float1)
Long12.l = Int(Float2)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To #Nb
Long21.l = Test(Float1)
Long22.l = Test(Float2)
Next
Time3 = ElapsedMilliseconds()
Texte.s = "Int :" + Chr(10) + "Time = " + Str(Time2 - Time1) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long11) + Chr(10) + StrF(Float2) + " -> " + StrF(Long12) + Chr(10) + Chr(10) + "Float - 0.5 to Long :" + Chr(10) + "Time = " + Str(Time3 - Time2) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long21) + Chr(10) + StrF(Float2) + " -> " + StrF(Long22) + Chr(10) + StrF((Time2 - Time1) / (Time3 - Time2), 1) + " time more fast"
SetClipboardText(Texte)
MessageRequester("Test", Texte)
Pour moi la fonction n'est plus que 4 fois plus rapide. Pas mal toujours, mais beaucoup moins impressionnant !!!
/Lio
Publié : mer. 27/mai/2009 13:11
par erix14
Pourquoi tu n'utilise pas la fonction ASM fistp ?
Code : Tout sélectionner
Procedure IntASM(f.f)
Protected i.i
FLD f
fistp i
ProcedureReturn i
EndProcedure
Publié : mer. 27/mai/2009 13:54
par cha0s
Intéressant :
Code : Tout sélectionner
Procedure IntASM(f.f)
Protected i.i
EnableASM
FLD f
FISTP i
DisableASM
ProcedureReturn i
EndProcedure
Float1.f = 5.958741545
Float2.f = 5
#Nb = 50000000
Time1 = ElapsedMilliseconds()
For i = 1 To #Nb
Long11.l = Int(Float1)
Long12.l = Int(Float2)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To #Nb
Long21.l = IntASM(Float1)
Long22.l = IntASM(Float2)
Next
Time3 = ElapsedMilliseconds()
Texte.s = "Int :" + Chr(10) + "Time = " + Str(Time2 - Time1) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long11) + Chr(10) + StrF(Float2) + " -> " + StrF(Long12) + Chr(10) + Chr(10) + "IntASM :" + Chr(10) + "Time = " + Str(Time3 - Time2) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long21) + Chr(10) + StrF(Float2) + " -> " + StrF(Long22) + Chr(10) + StrF((Time2 - Time1) / (Time3 - Time2), 1) + " time more fast"
SetClipboardText(Texte)
MessageRequester("Test", Texte)
Int :
Time = 3826 ms
5.958742 -> 5.000000
5.000000 -> 5.000000
Float - 0.5 to Long :
Time = 604 ms
5.958742 -> 6.000000
5.000000 -> 5.000000
6.3 time more fast
Publié : mer. 27/mai/2009 14:20
par erix14
Et avec une macro, c'est encore plus rapide
Code : Tout sélectionner
Macro FloatToInt(float,long)
FLD float
FISTP long
EndMacro
Float1.f = 5.958741545
Float2.f = 5
#Nb = 50000000
Time1 = ElapsedMilliseconds()
For i = 1 To #Nb
Long11.l = Int(Float1)
Long12.l = Int(Float2)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To #Nb
Long21.l
FloatToInt(Float1,Long21)
Long22.l
FloatToInt(Float2,Long22)
Next
Time3 = ElapsedMilliseconds()
Texte.s = "Int :" + Chr(10) + "Time = " + Str(Time2 - Time1) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long11) + Chr(10) + StrF(Float2) + " -> " + StrF(Long12) + Chr(10) + Chr(10) + "IntASM :" + Chr(10) + "Time = " + Str(Time3 - Time2) + " ms" + Chr(10) + StrF(Float1) + " -> " + StrF(Long21) + Chr(10) + StrF(Float2) + " -> " + StrF(Long22) + Chr(10) + StrF((Time2 - Time1) / (Time3 - Time2), 1) + " time more fast"
SetClipboardText(Texte)
MessageRequester("Test", Texte)
Publié : mer. 27/mai/2009 15:02
par lionel_om
erix14 a écrit :Et avec une macro, c'est encore plus rapide
Normal: dans tous les cas une macro sera plus rapide qu'une fonction...
/Lio

Publié : mer. 27/mai/2009 15:11
par erix14
@lionel_om : Bien sûr, c'est une évidence... dans cet exemple, une macro est plus qu'indiqué, car le code est très petit et le CPU passe plus de temps sur l'appel de la procédure que sur le contenu de la procédure.

Publié : mer. 27/mai/2009 16:52
par Fig
Question: Mais qu'est ce qui a bien pu être mis dans cette fonction int() nativement pour qu'elle soit si lente (?!!)

Publié : mer. 27/mai/2009 18:27
par Backup
erix14 a écrit :@lionel_om : Bien sûr, c'est une évidence... dans cet exemple, une macro est plus qu'indiqué, car le code est très petit et le CPU passe plus de temps sur l'appel de la procédure que sur le contenu de la procédure.

oui mais dans la mesure ou pour le purebasic, il s'agit bien d'une fonction 'int()'
je crois que de le faire en fonction est plus judicieux !!
le but final serai de remplacer celle existante

Publié : mer. 27/mai/2009 18:37
par djes
Fred a répondu dans le forum anglais.
Well int() is function, so you have a call function penality. And in the VC8 float->int conversion, it calls ftol2() which is another call. No wonder why it's slower. May be it could be optimized by inlining the function in the compiler, but it's optimization, not a bug.
Autrement dit, Int() est une fonction qu'a repris Fred du compilateur utilisé par la plupart des programmes créés sous Windows, y compris Purebasic (VC8, ça a été une révision majeure de PB il y a quelques temps). A mon avis Fred ne l'a pas inventé, comme beaucoup d'autres fonctions, d'autres s'y sont déjà employé qui ont pris en compte tout un tas de paramètres auxquels nous ne pensons même pas (rétro compatibilité, multi processeurs). Tout ça, ça implique des tas de conditions qui ralentissent forcément l'exécution d'une fonction. Or, dans le cas de quelque chose d'essentiel comme int(), c'est dommageable. C'est d'ailleurs ce genre de truc qui fait que windows est de plus en plus lent!
Fred pourrait effectivement créer une fonction optimisée, mais ce serait à ses risques et périls, et ce, pour toutes les fonctions bas niveau comme celle-là. Il le fait parfois
