So ihr lieben, ich wärme mal
diesen 3 Jahre alten Thread indirekt auf, da ich darauf aufbaue.
Es ging darum wieviele Teile / Baugruppen etc. im Modeling geladen sind, bzw. in einer Baugruppe vorhanden sind. Es gab damals Zaehlen.lsp und bisschen später von mir noch ein Zaehlen_20.lsp.
TEIL 1 : technische Erklärung
Stephan hatte seinerzeit zu Recht angemerkt, das er keine Perfomance-Verbesseung sieht in der Zaehlen_20.lsp Variante, sondern eher im Gegenteil (bei großen Baugruppen).
Nun ja... mir kam da schon vor vielen Monaten (18 oder mehr) der Geistesblitz warum das so ist!!!
Die schnelle Umsetzung scheiterte an meinen Erweiterungsideen, die ich im Hinterkopf hatte/habe. Aber auch aus anderen Gründen. So hat es etwas gedauert.
Erklärung:
Das folgende Konstrukt fand' ich damals recht elegant, um zu bestimmen wie viele (assemblies) in der Liste sind:
Code:
(count-if #'sd-inq-assembly-p all-obj)
Deswegen habe ich davon intensive Gebrauch gemacht, wie man in
Zaehlen_20.lsp sehen kann.
Aber genau DAS war der Fehler. Denn was macht diese Funktion: sie ruft für alle Elemente der Liste die Funktion sd-inq-assembly-p.
Wenn man nun mehrere solcher count-if's nutzt..... dannn ... hmmm
Code:
(setq ubgr (count-if #'sd-inq-assembly-p all-obj)
(setq dteil (count-if #'sd-inq-wire-part-p all-obj)
(setq fteil (count-if #'sd-inq-face-part-p all-obj)
(setq eteil (count-if #'sd-inq-empty-part-p all-obj)
Wenn meine all-obj Liste nun 1000 Elemente enthält, wird 1000 mal sd-inq-assembly-p gerufen und 1000 mal sd-inq-wire-part-p und 1000 mal sd-inq-face-part-p und 1000 mal sd-inq-empty-part-p.
Ja aber, wenn ich in 'Zeile 2' doch schon weiss, das es ein wire-part ist, warum sollte ich dann noch gucken ob das part ein face part oder empty ist???? Oder wenn es ein Assembly ist: warum prüfe ich auf wire/face/empty part???
Letzteres alleine sind 3000 Prüfungen für die Katz. 🐈
Ich habe mich vom hübschen count-if verleiten lassen und habe dies dann 16 mal auf 2 unterschiedliche Listen losgelassen. Und damit die Funktionaliät verschlimmbessert 😣
Kurz gesagt: Code elegant. 😎 Funktion lahm. 😖 - blöd g'loffe! 😬
Aber wie gesagt, der Geistes Blitz 💡 war da, geisterte lange Zeit nur im Hirn herum, aber nicht im lisp-code: eine gute alte dolist Schleife verwendet 👍, die ganzen Typprüfungen in einer Condition gemacht 👍, diese dann auch noch nach Häufigkeit geschickt sortiert 👍 (es gibt deutlich mehr Parts als Assemblies als Viewsets etc).
Code:
;; gekürzt:
(dolist (object all-objects)
(cond ;; on object type count
((sd-inq-part-p object)
(cond
((sd-inq-empty-part-p object) (incf cnt-part-empty))
((sd-inq-face-part-p object) (incf cnt-part-face))
((sd-inq-wire-part-p object) (incf cnt-part-wire))
(T #| :OTHERWISE |# (incf cnt-part-solid))
)) ; end cond-parts
((sd-inq-container-p object) (incf cnt-container))
((sd-inq-assembly-p object) (incf cnt-assemply))
;; usw...
) ; end cond
) ;; end loop
Die allermeisten Objekte werden jetzt also nur 1 bis 2 mal auf ihren objekt type geprüft und fertig.
Die Reduzierung auf die uniq-contents Objekte habe ich mit Hilfe von (sau-schnellen) hash tables umgesetzt. Da braucht es nun nicht mal mehr eine zweite Schleife/Liste. 🙂
Ich hatte noch 2 Ideen um noch Performance rauszukitzeln: a) den objekt type nur einmal erfragen b) den equal test für die Hashtables ersetzen.
Aber jetzt musste ich das ganze erste mal mit einem fetten Assembly und im "großen Modeling" testen und messen. Das geht zu Hause nicht mit der PE90.
------------------
● Firefox ESR ● Java Forum Stuttgart JUGS ● OSD Hilfeseite (de) / help page (en) ● NotePad++ ● BuFDi ●
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP