| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY bietet das umfangreichste Ökosystem von B2B als auch B2C-Lösungen für IT-Akteure auf dem Markt, eine Pressemitteilung
|
Autor
|
Thema: Doppelte Listeneinträge entfernen (2625 mal gelesen)
|
-ikarus- Mitglied Zeichner
Beiträge: 142 Registriert: 12.02.2007 ACAD 2015,PSP 2011, Showcase 2015, Mudbox 2015 Indesign CC, Illustrator CC, Photoshop CC, After Effects CC, Premiere Pro CC, Edge Animate CC, Acrobat DC Pro mit PitStop Pro, Visual Studio 2013 Notepad++ Rechner: HP Z620 Workstation NVIDIA Quadro K4000
|
erstellt am: 11. Apr. 2014 13:24 <-- editieren / zitieren --> Unities abgeben:
Hallo meine Frage, ich hab eine Liste der Blocknamen einer Auswahl von Blöcken erstellt. Mit (acad_strlsort nliste) sortiert ich die Liste Jetzt die Fage, wie kann ich doppelte Einträge aus der Liste entfernen? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 11. Apr. 2014 13:29 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
|
-ikarus- Mitglied Zeichner
Beiträge: 142 Registriert: 12.02.2007 ACAD 2015,PSP 2011, Showcase 2015, Mudbox 2015 Indesign CC, Illustrator CC, Photoshop CC, After Effects CC, Premiere Pro CC, Edge Animate CC, Acrobat DC Pro mit PitStop Pro, Visual Studio 2013 Notepad++ Rechner: HP Z620 Workstation NVIDIA Quadro K4000
|
erstellt am: 11. Apr. 2014 13:42 <-- editieren / zitieren --> Unities abgeben:
|
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1763 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 13. Apr. 2014 12:58 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo, ist in dem Link von CADffm betstimmt alles enthalten (ich habe mir nicht alles durchgelesen), aber folgender Code sollte funktionieren: Code:
(defun c:test ( / A LISTE N) (setq liste (acad_strlsort '( "wert1" "wert2" "wert23" "wert0" "wert1" "wert5" "wert5")) n -1) (vl-remove-if 'not (mapcar '(lambda(A) (setq n (+ n 1)) (if (> n 0) (if (/= (nth (- n 1)liste)A) A) A))liste)))
Schönes WE ------------------ viele Grüße Jörn http://www.bosse-engineering.com Rahmen einfügen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Theodor Schoenwald Ehrenmitglied
Beiträge: 1672 Registriert: 16.04.2002
|
erstellt am: 13. Apr. 2014 20:33 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo, oder so: ;; ---------------------------------- (defun REMOVE_DOUBLES (LST) (if LST (cons (car LST) (REMOVE_DOUBLES (vl-remove (car LST) LST))) ) ) ;; ---------------------------------- Gruß Theodor Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
-ikarus- Mitglied Zeichner
Beiträge: 142 Registriert: 12.02.2007 ACAD 2015,PSP 2011, Showcase 2015, Mudbox 2015 Indesign CC, Illustrator CC, Photoshop CC, After Effects CC, Premiere Pro CC, Edge Animate CC, Acrobat DC Pro mit PitStop Pro, Visual Studio 2013 Notepad++ Rechner: HP Z620 Workstation NVIDIA Quadro K4000
|
erstellt am: 14. Apr. 2014 06:49 <-- editieren / zitieren --> Unities abgeben:
Danke Euch, hab mir mit dem Link von cadffm weitergeholfen, aber es ist schon interessant, wie viele Möglichkeiten es gibt. Außerdem hat es mir geholfen meinen Horizont wieder etwas zu erweitern. Danke Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 14. Apr. 2014 13:21 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo Theodor ich habe mal deine Funktion ausprobiert mit der ersten Liste aus dem verlinkten Beitrag und bei mir bekommt sie kalte Füße ich musste sie abbrechen weil es einfach viel zu lange dauerte. Hier mein Testcode: Code: (SETQ i 1.0) (SETQ Liste1 nil) (REPEAT 5000 (SETQ Liste1 (CONS i (CONS (1+ i) Liste1)) i (+ 2 i) ) ) (defun REMOVE_DOUBLES (LST) (if LST (cons (car LST) (REMOVE_DOUBLES (vl-remove (car LST) LST))) ) ) (REMOVE_DOUBLES Liste1)
Kann das noch jemand nachvollziehen ? ------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 14. Apr. 2014 20:04 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin:
Code:
(defun REMOVE_DOUBLES (LST) (if LST (cons (car LST) (REMOVE_DOUBLES (vl-remove (car LST) LST))) ) )
Kann das noch jemand nachvollziehen ?
Ja, ist doch einfach. Er nimmt das erste Element der Liste, und hängt das vor eine bereinigte Liste. Aus der bereinigten ist erstens mit VL-REMOVE jedes Vorkommen des ersten gelöscht, und zweitens rekursiv mit derselben Methode auch jedes doppelte Vorkommen irgend welcher anderen Elemente. IMO kann man sich hier den Overhead mit der Rekursion sparen, und wird dabei vermutlich Perfomance gewinne. Ich mach' das so:
Code:
(defun removeduplicate (lst / result) (while lst (setq result (cons (car lst) result)) (setq lst (vl-remove (car lst) lst)) ) (reverse result) )
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 15. Apr. 2014 13:17 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo, ich habe mir das ganze nochmal angesehen da ich das ganze mit dem Beitrag "Doppelte Listeneinträge entfernen Lisp" und den Zeitmessungen ganz spaßig fand. Wobei es dort um die Vermeidung von VL ging. Aber in diesem Beitrag nicht. Daher erst mal @archtools ich hätte erwähnen sollen das mir der Ablauf klar ist und ich eigentlich nur hinweisen wollte das der Hinweis von Theodor nicht zum gewünschten Erfolg führt und damit nur sicherstellen das es nicht nur bei mir fehlerhaft ist zudem kommst du mit deinem removeduplicate auch nicht an die vorgelegte Performance der anderen (DOUB-CADWIESEL) heran. Und da ich nicht nur auf Fehler hinweisen möchte habe ich einen Versuch gewagt es besser zu machen daher auch bitte wenn wewüscht meinen Versuch anzweifeln. Dabei ist mir noch aufgefallen das in dem Zeiterfassungstool von CAD-Huebner die Liste 3 nicht stimmt hier wären es nicht wie angegeben 50% doppelte sondern nur 25% es sei denn man ändert die der Zusammenstellung der Liste 3 den Wert von 5000 auf 10000 da ja I+2 ist. Aber das ist für die Sache ganz egal. Code: (defun DOUB-MELDIN (LST / ListeDOUB) (vl-sort (setq LST(vl-sort LST '< )) (function (lambda (s1 s2)(if (eq s1 s2)(setq ListeDOUB (cons s1 ListeDOUB))))) ) (foreach teil ListeDOUB (setq LST (vl-remove teil LST))) (foreach teil ListeDOUB (setq LST (cons teil LST))) LST )
------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Theodor Schoenwald Ehrenmitglied
Beiträge: 1672 Registriert: 16.04.2002
|
erstellt am: 15. Apr. 2014 14:25 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo Wolfgang, in einem vorhergehenden Beitrag ist folgende Liste zum testen: ("wert1" "wert2" "wert23" "wert0" "wert1" "wert5" "wert5") Die Beispielliste habe ich genommen und getestet. ;; ------------- Testdatei --------------- (defun C:TEST (/ L1 L2) (setq L1 '("wert1" "wert2" "wert23" "wert0" "wert1" "wert5" "wert5")) (prompt "\nL1: ") (princ L1) (setq L2 (REMOVE_DOUBLES L1)) (prompt "\nL2: ") (princ L2) (princ) ) (defun REMOVE_DOUBLES (LST) (if LST (cons (car LST) (REMOVE_DOUBLES (vl-remove (car LST) LST))) ) ) ;; ----------------------------- Das Ergebnis: Befehl: TEST L1: (wert1 wert2 wert23 wert0 wert1 wert5 wert5) L2: (wert1 wert2 wert23 wert0 wert5) Was ist daran nicht in Ordnung? Gruß Theodor
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 15. Apr. 2014 14:31 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin:
Dabei ist mir noch aufgefallen das in dem Zeiterfassungstool von CAD-Huebner die Liste 3 nicht stimmt hier wären es nicht wie angegeben 50% doppelte sondern nur 25% es sei denn man ändert die der Zusammenstellung der Liste 3 den Wert von 5000 auf 10000 da ja I+2 ist. Aber das ist für die Sache ganz egal.Code: (defun DOUB-MELDIN (LST / ListeDOUB) (vl-sort (setq LST(vl-sort LST '< )) (function (lambda (s1 s2)(if (eq s1 s2)(setq ListeDOUB (cons s1 ListeDOUB))))) ) (foreach teil ListeDOUB (setq LST (vl-remove teil LST))) (foreach teil ListeDOUB (setq LST (cons teil LST))) LST )
Wenn's Dir um Performance geht, dann solltest Du wissen, dass diese natürlich von der Länge der Liste abhängt. Rekursion ist gut bei kürzeren Listen, Schleifen sind besser bei längeren Listen. Das hat ganz simpel mit der Speicherverwaltung zu tun, denn bei Rekursion wird da ein ziemlich großer Overhead aufgebaut. Im konkreten Fall: Bei 2000 Elementen ist Rekursion noch geringfügig besser meine Schleife, bei 3000 Elementen ist meine Schleife geringfügig besser als Rekursion (jeweils etwa 10 bis 15%). Bei 10.000 Elementen aber dauert (auf meinem Notebook mit i3 Prozessor und 4 GByte RAM) die Rekursion schon 30 mal länger als meine Schleife. Deine Lösung braucht bei 10.000 Elementen etwa 3 mal so lange wie die Rekursion, also etwa etwa 100 mal so lange wie die Schleife. CADWiesels Version habe ich nicht heruntergeladen und also auch nicht getestet. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 15. Apr. 2014 15:36 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
@ Theodor -ikarus- hat keine Vorgabe gegeben wie lang seine Liste ist als bin ich auch der Liste des vorhergehenden Beitrag gefolgt. 10000. Da wird dein Code viel zu langsam. Ansonsten ist er in Ordnung. @ archtools Anhand der Auswertung von CAD-Huebner liegen mir folgende Auswertungen mit den verschiedenen Listenlängen vor. Wie hast du es getestet? Mit 2000 Einträgen!
Zitat: Test beginnt...0% Doppelte... (DOUB-CADWIESEL 0.227 sec.) (DOUB-MELDIN 0.011 sec.) (REMOVEDUPLICATE 0.174 sec.) 50% Doppelte... Member findet sofort (DOUB-CADWIESEL 0.059 sec.) (DOUB-MELDIN 0.006 sec.) (REMOVEDUPLICATE 0.105 sec.) 50% Doppelte... Member findet zuletzt (DOUB-CADWIESEL 0.22 sec.) (DOUB-MELDIN 0.012 sec.) (REMOVEDUPLICATE 0.172 sec.) 100% Doppelte... (DOUB-CADWIESEL 0.03 sec.) (DOUB-MELDIN 0.006 sec.) (REMOVEDUPLICATE 0.002 sec.) Test beendet.
Mit 3000 Einträgen! Zitat: Test beginnt...0% Doppelte... (DOUB-CADWIESEL 0.484 sec.) (DOUB-MELDIN 0.015 sec.) (REMOVEDUPLICATE 0.408 sec.) 50% Doppelte... Member findet sofort (DOUB-CADWIESEL 0.127 sec.) (DOUB-MELDIN 0.009 sec.) (REMOVEDUPLICATE 0.201 sec.) 50% Doppelte... Member findet zuletzt (DOUB-CADWIESEL 0.348 sec.) (DOUB-MELDIN 0.134 sec.) (REMOVEDUPLICATE 0.321 sec.) 100% Doppelte... (DOUB-CADWIESEL 0.038 sec.) (DOUB-MELDIN 0.01 sec.) (REMOVEDUPLICATE 0.005 sec.) Test beendet.
Mit 10.000 Einträgen! Zitat: Test beginnt...0% Doppelte... (DOUB-CADWIESEL 5.263 sec.) (DOUB-MELDIN 0.058 sec.) (REMOVEDUPLICATE 4.75 sec.) 50% Doppelte... Member findet sofort (DOUB-CADWIESEL 1.332 sec.) (DOUB-MELDIN 0.028 sec.) (REMOVEDUPLICATE 2.323 sec.) 50% Doppelte... Member findet zuletzt (DOUB-CADWIESEL 3.293 sec.) (DOUB-MELDIN 1.811 sec.) (REMOVEDUPLICATE 4.068 sec.) 100% Doppelte... (DOUB-CADWIESEL 0.054 sec.) (DOUB-MELDIN 0.012 sec.) (REMOVEDUPLICATE 0.004 sec.) Test beendet.
------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 15. Apr. 2014 16:05 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin: @ Theodor -ikarus- hat keine Vorgabe gegeben wie lang seine Liste ist als bin ich auch der Liste des vorhergehenden Beitrag gefolgt. 10000. Da wird dein Code viel zu langsam. Ansonsten ist er in Ordnung.@ archtools Anhand der Auswertung von CAD-Huebner liegen mir folgende Auswertungen mit den verschiedenen Listenlängen vor. Wie hast du es getestet?
Du hast recht: außer der Listenlänge selbst spielt bei den verschiedenen Varianten natürlich noch eine große Rolle, wieviele Doppelte vorkommen, und teilweise sogar, wie stark verstreut die sind. Ich hatte nur Listen verglichen, in denen jedes Element genau zweimal vorkam (ich nehme an, das ist das, was Du mit "100% Doppelte" meinst). Für den Test ist unbedingt wichtig, dass zwischen den Tests eine Garbage Collection läuft. Also jeweils ein (gc) vor dem Funktionsaufruf setzen, sonst werden werden die später aufgerufenen Funktionen benachteiligt. Und dann hängt speziell das Verhalten der Rekursion davon ab, wie viel physikalisches RAM zur Verfügung steht. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 16. Apr. 2014 11:16 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Also nach einigen Tests sollte Aufgrund eines Fehlers meinem Code erstmals nicht verwendet werden Sorry. ------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 17. Apr. 2014 12:35 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
So dann noch eben die Korrektur damit sollten doppelte Elemente in einer Liste zügig entfernt werden. Hoffe ich Code: (defun DOUB-MELDIN (LST / DOUB) (vl-sort (setq LST (vl-sort LST '< )) (function(lambda (x y)(if (and(= x y)(not(=(car DOUB)x)))(setq DOUB (cons x DOUB)))))) (foreach teil DOUB (setq LST (vl-remove teil LST))) (append LST DOUB) )
------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 17. Apr. 2014 13:14 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin: So dann noch eben die Korrektur damit sollten doppelte Elemente in einer Liste zügig entfernt werden. Hoffe ich
Code: (defun DOUB-MELDIN (LST / DOUB) (vl-sort (setq LST (vl-sort LST '< )) (function(lambda (x y)(if (and(= x y)(not(=(car DOUB)x)))(setq DOUB (cons x DOUB)))))) (foreach teil DOUB (setq LST (vl-remove teil LST))) (append LST DOUB) )
Ja, diese Variante ist in der Tat sehr schnell. Ich hab' eine Liste mit 50.000 maximal dreistelliger zufallsgenerierter Integers konstruiert (784 verschiedene Elemente): Test1 While: 2.34 Sekunden Test2 Rekursion CONS: 6.536 Sekunden Test3 Rekursion APPEND: 8.205 Sekunden Test4 Meldin: 0.015 Sekunden Die Variante mit APPEND sollte der Lehrmeinung nach erheblich langsamer sein als die mit CONS, aber das bestätigt sich bei kürzeren Listen nicht. Bei 10.000 Elementen ist APPEND sogar schneller. Ganz extrem wirkt sich aus, wenn die Liste (50.000 Elemente, 784 verschiedene) sortiert ist: Test1 While: 0.031 Sekunden Test2 Rekursion CONS: 0.078 Sekunden Test3 Rekursion APPEND: 0.109 Sekunden Test4 Meldin: 0.015 Sekunden Da zeigt sich, dass logischerweise bei Test 1 bis 3 ein Großteil der Performance für's vl-remove verloren geht, dessen Algorithmus mit sortierten Listen sehr viel besser klar kommt. Darin dürfte auch der wesentliche Perfomancegewinn von Meldins Algorithmus begründet sein, denn er arbeitet ja mit einer sortierten Liste, und gibt damit auch ein anderes Ergebnis aus als die Wettbwerber. Lässt man die Konkurrenz auch sortieren (Sortierzeit in Laufzeitmessung integriert), dann schrumpft der Performancegewinn von Meldin: Test1 While: 0.031 Sekunden Test2 Rekursion CONS: 0.047 Sekunden Test3 Rekursion APPEND: 0.094 Sekunden Test4 Meldin: 0.016 Sekunden Die Laufzeit weicht übrigens bei aufeinander folgenden Tests stark voneinander ab, obwohl ich zwischen den Tests ein (gc) aufrufe: Command: (test) Test1 While: 0.047 Sekunden Test2 Rekursion CONS: 0.093 Sekunden Test3 Rekursion APPEND: 0.14 Sekunden Test4 Meldin: 0 Sekunden Command: (test) Test1 While: 0.047 Sekunden Test2 Rekursion CONS: 0.093 Sekunden Test3 Rekursion APPEND: 0.156 Sekunden Test4 Meldin: 0.016 Sekunden Command: (test) Test1 While: 0.062 Sekunden Test2 Rekursion CONS: 0.094 Sekunden Test3 Rekursion APPEND: 0.171 Sekunden Test4 Meldin: 0.015 Sekunden IMO einzig denkbare Ursache dafür ist wohl die Speicherverwaltung des Rechners. Zwischen den Tests wird jeweils ein (gc) ausgeführt, aber das setzt den Speicher wohl nicht wirklich zurück. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 17. Apr. 2014 13:37 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Ohne das ich es jetzt extra noch mal teste: Axel hat zu Lebzeiten schon gesagt (und im Tutorial für Meinereiner auch geschrieben), das der Unterschied con Cons und Append in einer Rekursion sich praktisch nicht zeigt. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 17. Apr. 2014 13:59 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
@ archtools Schade das du die einzelnen Funktionen und deine Listen Konstruktion nicht gepostet hast. Aber probiere es mal mit der Liste. Code: (SETQ i 1.0) (REPEAT 5000 (SETQ Liste (CONS (- 5000 i) (CONS i Liste)) i (+ 2 i) ) )
Und zeig dann mal was hier deine Zeiten sagen. @CadFFM Achtung es kommt immer darauf an was man verwursten will Append ist für listen gedacht nicht für einzelene Elemente da hat cons die Nase vorn, habe damals dafür einen Test erstellt solltest du dir mal ansehen Append gegen Cons ------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. [Diese Nachricht wurde von Meldin am 17. Apr. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 17. Apr. 2014 18:11 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin: @ archtools Schade das du die einzelnen Funktionen mit und deine Listen Konstruktion nicht gepostet hast. Aber probiere es mal mit der Liste.Code: (SETQ i 1.0) (REPEAT 5000 (SETQ Liste (CONS (- 5000 i) (CONS i Liste3)) i (+ 2 i) ) )
Und zeig dann mal was hier deine Zeiten sagen.@CadFFM Achtung es kommt immer darauf an was man verwursten will Append ist für listen gedacht nicht für einzelene Elemente da hat cons die Nase vorn, habe damals dafür einen Test erstellt solltest du dir mal ansehen Append gegen Cons
Ich weiss, wie Lisp-Interpreter gebaut werden. APPEND muss im Speicher grundsätzlich eine neue Liste aufbauen, während CONS lediglich zwei Pointer vor eine Liste setzt. Wegen der großen Cache-Speicher moderner Prozessoren spielt das aber - jedenfalls bis zu einer gewissen Listenlänge - keine Rolle mehr. Wenn ich in Deiner Liste (Variable Liste3 natürlich durch Liste korrigiert) den Test laufen lasse, dann ist das Ergebnis so: Test1 While: 4.898 Sekunden Test4 Meldin: 2.823 Sekunden Die beiden Rekursionstests hab' ich jeweils nach etwa einer Minute abgebrochen. Die Verteilung macht's für die Rekursion praktisch unmöglich. Meine Listen erzeuge ich mit unterem Code, z.B. mit (random 10000 3) erzeugt eine Liste aus 10.000 maximal dreistelligen Zufallszahlen. Code:
(defun random (len dig / lst) (repeat len (setq lst (cons (fix (* (expt 10 dig) (/ (setq *seed* (rem (+ (* 25173 (:t-seed)) 13849) 65536)) 65536.0 ) ) ) lst ) ) ) )(defun randomseed () (cond (*randomseed*) ((setq *randomseed* (getvar "date"))) ) )
Mit einer Liste aus 10.000 dreistelligen Zufallszahlen (darin kommen alle Zahlen von 0 bis 999 vor) sieht das Ergebnis dann so aus: Test1 While: 0.515 Sekunden Test2 Rekursion CONS: 1.389 Sekunden Test3 Rekursion APPEND: 1.513 Sekunden Test4 Meldin: 0.031 Sekunden Mit einer Liste aus 10.000 vierstelligen Zufallszahlen (darin kommen - zufällig - nur 6284 verschiedene Zahlen von 0 bis 9999 vor) sieht das Ergebnis dann so aus: Test1 While: 5.133 Sekunden Test4 Meldin: 0.187 Sekunden Rekursion wurde abgebrochen. Bei 50.000 dreistelligen Zahlen: Test1 While: 3.151 Sekunden Test4 Meldin: 0.172 Sekunden Wenn Test1 die Zahlen auch sortiert, dann sieht's bei den 50.000 so aus: Test1 While: 0.203 Sekunden Test4 Meldin: 0.172 Sekunden Schneller als Deine Funktion ist meine nur dann, wenn in einer großen Liste wenige verschiedene Elemente vorkommen, denn die Zahl meiner Schleifendurchgänge ist genau die Zahl verschiedener Elemente. Die Rekursion ist zwar eleganter als alle anderen, und kommt zudem ohne SETQ aus, aber sie kann einem auch um die Ohren fliegen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Meldin Mitglied
Beiträge: 398 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 18. Apr. 2014 10:09 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Hallo, Zitat: Schneller als Deine Funktion ist meine nur dann, wenn in einer großen Liste wenige verschiedene Elemente vorkommen, denn die Zahl meiner Schleifendurchgänge ist genau die Zahl verschiedener Elemente. Die Rekursion ist zwar eleganter als alle anderen, und kommt zudem ohne SETQ aus, aber sie kann einem auch um die Ohren fliegen.
und genau da liegt der Punkt wann hat man Listen die man so auswertet von denen man weiß wie lang und wie viel doppelte enthalten sind. Wenn man das wüsste hätte man bestimmt schon vorher filtern können. Hier denke ich spielt das Verhältnis zur Zeit eine größere Rolle. Hier fehlt natürlich deine Angabe wie schnell dein Versuch zu meinem war. Für den einen speziellen Fall denke ich gibt es vielleicht noch schnellere als deine. Z.B. diese eventuell Code: (defun DOUB-MELDIN1 (LST1 / DOUB) (setq LST1 (vl-sort LST1 '< )) (while (vl-some '(lambda (x y) (if (and (= x y) (not (= (car DOUB) x))) (setq DOUB (cons x DOUB)))) LST1 (cdr LST1) ) (setq LST1 (vl-remove (car DOUB) LST1)) ) (append DOUB LST) )
Für eine Auswertung mit dieser Liste Code: (SETQ i 1.0) (REPEAT 5000 (SETQ Liste (CONS (- 5000 i) (CONS i Liste)) i (+ 2 i) ) )
benötigt sie bei mir ca. 6 sek. und DOUB-MELDIN nur ca. 3 sek. in allen anderen Tests ist sie im tausendstel Bereich schneller. Daher habe ich diese Variante vernachlässigt. Denn nur für eine Auswertung zu erhalten wäre es mir egal ob ich 0.1 sek. oder 0.2 sek. warte, ich schätze mal das es sich um solche Zeitspannen bei deiner Variante handelt. Anders aber wie in deinem Beispiel ich 0.2 sek. warte oder 5 sek. bei deiner Auswertung. ------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 die aus unerklärlichen Gründen aus dem System hier gelöscht wurden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 18. Apr. 2014 11:00 <-- editieren / zitieren --> Unities abgeben: Nur für -ikarus-
Zitat: Original erstellt von Meldin: Hallo, und genau da liegt der Punkt wann hat man Listen die man so auswertet von denen man weiß wie lang und wie viel doppelte enthalten sind.
Um das Thema abzuschließen: Deine Variante ist sehr schnell, aber sie sortiert die Liste, und das ist ein unerwünschter Seiteneffekt. Ich will nur die doppelten Listeneinträge entfernen, un dsonst nix verändern. Die Rekursion explodiert bei großen Listen mit wenigen Doppelten. Deshalb bleib' ich bei meiner Funktion. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |