Aller au contenu

Messages recommandés

Posté(e)

Salut à tous!

 

Ayant développé une appli pour le boulot, une fois que ca marche, je cherche à améliorer

si je suis motivé.

Comme je faisais des boucles while, je me suis dit, on passe à foreach. J'ai modifié le code, lancé

le nouveau lisp. et là :o :o horreur :o :o le temps de recherche est multiplié par 2!

 

Avec le lisp benchmark (que gile m'a fourni) j'ai fait des essais, comme mon lisp utilise des fonctions récursives: une fonction while simple et une récursive de même pour foreach.

 

Voilà le lisp de test et les résultats

 
(defun fwhile1( lst / cpt lg res)

(setq cpt 0 lg (length lst) res nil)

 	(while (< cpt lg)
	(if (= (nth cpt lst) 2)
		(setq res t)
	) ; if
  	(setq cpt (1+ cpt))
) ; while

 	res
) ; fwhile1

(defun ffor1( lst / elem res)

(setq res nil)

 	(foreach elem lst
	(if (= elem 2)
		(setq res t)
	) ; if
) ; foreach

 	res
) ; ffor1

(defun fwhile2( lst / cpt lg res)

(setq cpt 0 lg (length lst) res nil)

 	(while (< cpt lg)
	(if (= (nth cpt lst) 2)
		(setq res t)
	) ; if
  	(fwhile2 (cdr lst))
  	(setq cpt (1+ cpt))
) ; while

 	res
) ; fwhile2

(defun ffor2( lst / elem res)

(setq res nil)

 	(foreach elem lst
	(if (= elem 2)
		(setq res t)
	) ; if
  	(ffor2 (cdr lst))
) ; foreach

 	res
) ; ffor2

(setq VAR_LG 1)


(defun test1( / lst)

(setq cpt 1 lst '(1))



(while (< cpt VAR_LG)
	(setq lst (append lst (list cpt)) cpt (1+ cpt))
) ; while


 	(print (strcat "Comparaison avec: " (itoa VAR_LG) " éléments"))
 	(print)
;(benchmark '((fwhile1 lst)(ffor1 lst)))

 	(setq VAR_LG (* 10 VAR_LG))
) ; test

(setq nb 0 nb_f 5)
(while (< nb nb_f)
(test1)
 	(setq nb (1+ nb))
)

(setq VAR_LG 11)


(defun test2( / lst)

(setq cpt 1 lst '(1))



(while (< cpt VAR_LG)
	(setq lst (append lst (list cpt)) cpt (1+ cpt))
) ; while


 	(print (strcat "Comparaison avec: " (itoa VAR_LG) " éléments"))
 	(print)
(benchmark '((fwhile2 lst)(ffor2 lst)))

 	(setq VAR_LG (1+(1+ VAR_LG)))
) ; test

(setq nb 0 nb_f 6)
(while (< nb nb_f)
(test2)
 	(setq nb (1+ nb))
)


"Comparaison avec: 1 éléments" 
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

   (FWHILE1 LST).....1344 / 1.05 
   (FFOR1 LST).......1406 / 1.00 

"Comparaison avec: 10 éléments" 
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

   (FFOR1 LST).......1578 / 1.07 
   (FWHILE1 LST).....1688 / 1.00 

"Comparaison avec: 100 éléments" 
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

   (FFOR1 LST).......1656 / 1.79 
   (FWHILE1 LST).....2969 / 1.00 

"Comparaison avec: 1000 éléments" 
Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s):

   (FFOR1 LST).......1297 / 7.38 
   (FWHILE1 LST).....9578 / 1.00 

"Comparaison avec: 10000 éléments" 
Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s):

   (FFOR1 LST)........1515 / 62.61 
   (FWHILE1 LST).....94859 / 1.00 

 

En appel simple, le foreach est bien plus rapide lorsqu'il y a beaucoup de données (en fait pour 4 éléments

le foreach et le while sont équivalents)

 

"Comparaison avec: 1 éléments" 
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

   (FWHILE2 LST).....1343 / 1.07 
   (FFOR2 LST).......1437 / 1.00 

"Comparaison avec: 3 éléments" 
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

   (FWHILE2 LST).....1204 / 1.18 
   (FFOR2 LST).......1422 / 1.00 

"Comparaison avec: 5 éléments" 
Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s):

   (FWHILE2 LST).....1578 / 1.36 
   (FFOR2 LST).......2141 / 1.00 

"Comparaison avec: 7 éléments" 
Benchmarking .........Elapsed milliseconds / relative speed for 64 iteration(s):

   (FWHILE2 LST).....1938 / 1.43 
   (FFOR2 LST).......2766 / 1.00 

"Comparaison avec: 9 éléments" 
Benchmarking ...Elapsed milliseconds / relative speed for 1 iteration(s):

   (FWHILE2 LST).....2187 / 1.42 
   (FFOR2 LST).......3110 / 1.00 

"Comparaison avec: 11 éléments" 
Benchmarking ...Elapsed milliseconds / relative speed for 1 iteration(s):

   (FWHILE2 LST).....240422 / 1.66 
   (FFOR2 LST).......400187 / 1.00 

Et bien là, c'est plus le cas :o. Bon je sais, la différence est moins flagrante, mais apparement

en appel récursif, le foreach perd en efficacité

Tous pour lisp, Lisp pour tous!

Avec Revit, cela ne vas trop vite...

Posté(e)

SAlut Patrick_35!

 

Et en itératif ?

Dans le sens (while (while (while ) ) ) contre (foreach (foreach (foreach )))?

 

Benchmark fait déjà de l'itératif, puisqu'il lance un certain nombre de fois.

 

[Edité le 25/10/2007 par bseb67]

Tous pour lisp, Lisp pour tous!

Avec Revit, cela ne vas trop vite...

Posté(e)

Salut,

 

Si j'ai bien compris, tu veux comparer les vitesses d'exécution de foreach et while sur la totalité des éléments d'une liste.

Peu importe le résultat de la routine, car sinon un while ou une fonction récursive avec une condition d'arrêt sur "res" seraient plus rapides en arrêtant l'évaluation dès que res est T.

 

Une petite remarque, tes fonctions récursives sont un mélange de récursivité et d'itérativité, elles sont d'ailleurs beaucoup moins rapides que fwhile1 et ffor1.

 

S'il faut évaluer tous les éléments d'une liste, on peut aussi utiliser mapcar ou repeat. J'ai donc poussé un peu plus ton test en ajoutant frepaet1, fmapcar1 et une fonction récursive qui fait la même chose.

 

(defun frepeat1 (lst / cpt res)

 (setq cpt 0)
 (repeat (length lst)
   (if	(= (nth cpt lst) 2)
     (setq res t)
   )
   (setq cpt (1+ cpt))
 )

 res
)

(defun fmapcar1 (lst / res)

 (mapcar '(lambda (x)
     (if (= x 2)
       (setq res T)
     )
   )
  lst
 )
 
 res
)

(defun frecurs (lst / res)
 (if lst
   (progn
     (if (= (car lst) 2)
(setq res T)
     )
     (frecurs (cdr lst))
   )
 )

 res
) 

 

Les résultats :

 

"Comparaison avec: 1 éléments"

Benchmarking ...................Elapsed milliseconds / relative speed for 65536 iteration(s):

 

(FRECURS LST)......1937 / 1.15

(FWHILE1 LST)......2016 / 1.11

(FFOR1 LST)........2110 / 1.06

(FREPEAT1 LST).....2203 / 1.01

(FMAPCAR1 LST).....2235 / 1.00

 

"Comparaison avec: 10 éléments"

Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

 

(FMAPCAR1 LST).....1235 / 1.25

(FFOR1 LST)........1297 / 1.19

(FRECURS LST)......1313 / 1.18

(FWHILE1 LST)......1391 / 1.11

(FREPEAT1 LST).....1547 / 1.00

 

"Comparaison avec: 100 éléments"

Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

 

(FMAPCAR1 LST).....1203 / 2.95

(FFOR1 LST)........1765 / 2.01

(FRECURS LST)......2297 / 1.54

(FWHILE1 LST)......3141 / 1.13

(FREPEAT1 LST).....3546 / 1.00

 

"Comparaison avec: 1000 éléments"

Benchmarking ...............Elapsed milliseconds / relative speed for 4096 iteration(s):

 

(FMAPCAR1 LST)......1875 / 12.74

(FFOR1 LST).........3250 / 7.35

(FRECURS LST).......4672 / 5.11

(FWHILE1 LST)......22953 / 1.04

(FREPEAT1 LST).....23891 / 1.00

 

"Comparaison avec: 10000 éléments"

Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s):

 

(FMAPCAR1 LST).......1141 / 102.58

(FFOR1 LST)..........1969 / 59.44

(FRECURS LST)........3953 / 29.61

(FWHILE1 LST)......116015 / 1.01

(FREPEAT1 LST).....117047 / 1.00

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut Gile!

 

En fait, mon lisp que je cherchais à améliorer ne fait qu'un simple test.

J'ai du récursif avec des sous fonctions

(fg

( while

 

(f1)

 

(while

(while

(while

(f5)

)

)

)

)

)

 

(f1

(while f2)

(while f3)

(while f4)

(while f1)

)

(f2

(while )

)

(f3

(while )

)

(f4

(while )

)

 

(f5

(while

(f6)

)

)

 

(f6

(while )

)

 

Voilà le squelette des while.

donc voulant gagner du temps, j'ai essayé en remplacant tout par des foreach sauf lorsqu'il y a un booléen de fin pour le while.

Et bien c'est là que je suis passé de 47s à 108s pour (fg)

Tous pour lisp, Lisp pour tous!

Avec Revit, cela ne vas trop vite...

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité