INT : Fonction trop lente

Archive.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

INT : Fonction trop lente

Message 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 ?
Dernière modification par Le Soldat Inconnu le mar. 26/mai/2009 19:47, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Message 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
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message 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 ! 8O

Une question (bête, sans doute): à quoi sert le "-0.5" ?
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message 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
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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... 8O
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message 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)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message 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
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message 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
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message 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
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

Et avec une macro, c'est encore plus rapide :wink:

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)
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

erix14 a écrit :Et avec une macro, c'est encore plus rapide :wink:
Normal: dans tous les cas une macro sera plus rapide qu'une fonction...
/Lio :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message 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. :wink:
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Question: Mais qu'est ce qui a bien pu être mis dans cette fonction int() nativement pour qu'elle soit si lente (?!!) 8O
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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. :wink:
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 :)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message 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 :)
Répondre