amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Wieviele Files in Dir? [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 3 [ - Beitrag schreiben - ]

30.12.2011, 17:39 Uhr

AGSzabo
Posts: 1663
Nutzer
Hallo,

gibt es einen schnellen Weg, heraus zu finden, wie viele Dateien in einem Verzeichnis sind? ExNext() loop wäre zu aufwendig, glaube ich.
--
Author of Open eXternal User Interfaces - Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

31.12.2011, 11:42 Uhr

Thore
Posts: 2266
Nutzer
ExNext ist durchaus ein üblicher Weg. Es gibt aber noch ExAll.
Vorgehensweise:
1. Verzeichnis locken
2. ExAllControl reservieren
3. ExAll aufrufen (und EAC Struktur damit füllen)
4. eac_Entries enthält Anzahl Dateien
5. ExAllContol free

ungefähr so (Bitte "more" noch prüfen obs gültig ist, hab ich jetzt auf die Schnelle nicht gemacht, aber Du solltest es):

#include <exec/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos/dos.h>
#include <dos/exall.h>
#include <dos/dostags.h>



int GetNumFiles(char *directory)
{
struct ExAllControl *eac;
BPTR mylock;
int more;
int num = 0;
struct ExAllData ExAllBuf[20];

if(mylock = Lock(directory, SHARED_LOCK))
{

if (eac = (struct ExAllControl *)AllocDosObjectTags(DOS_EXALLCONTROL,TAG_END))
{
eac->eac_LastKey = 0;
eac->eac_Entries = 0;
eac->eac_MatchString = NULL;
eac->eac_MatchFunc = NULL;

more = ExAll(mylock, ExAllBuf, sizeof(ExAllBuf), ED_TYPE, eac);

num = eac->eac_Entries;

FreeDosObject(DOS_EXALLCONTROL,eac);
return (num);
}
}
}


[ Dieser Beitrag wurde von Thore am 31.12.2011 um 11:44 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

31.12.2011, 11:58 Uhr

AGSzabo
Posts: 1663
Nutzer
@Thore:

Das Dumme ist nur, ich habe es ausprobiert, dass das Durchgehen mit ExNext() fast genauso lange dauert, wie dann das Einlesen der Liste selber. Ich bezweifele dass es mit ExAll schneller geht. Ich möchte doch einen Progressbar machen.

Sogar das Hostsystem Ubuntu Linux braucht seine Zeit, bis es das Testdir mit ca 2000 Dateien eingelesen hat.

ps: was ist, wenn der buffer nicht für alles filenamen aus reicht? ich habe in den docs gelesen dass mindestens der dateiname ...

... und dass man, wenn more gesetzt ist, das ganze nochmal und nochmal aufrufen müsste ...



[ Dieser Beitrag wurde von AGSzabo am 31.12.2011 um 12:07 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

31.12.2011, 12:19 Uhr

Thore
Posts: 2266
Nutzer
Kommt drauf an was Du anforderst. Ich hab hier im Demo ED_TYPE verwendet, das reicht mir für die Anzahl. Mit den 20 im Buffer kommt man natürlich nicht so weit, da sist ja nur ein Demo.
Er stoppt automatisch bei der maximalen Anzahl die in den Buffer passen, aufgrund des sizeof im Befehl. Bei einer Anzahl von 20 können maximal 42 Objekte (pro Durchlauf) gefunden werden. Nimmst Du einen Wert von 10000 bist Du schon jenseits des was die meisten in einem Verzeichnis haben.
Mit einer Schleife kannst Du natürlich auch die 20 im Buffer lassen. Das wär für eine Progressbar sogar der saubere Weg.


[ Dieser Beitrag wurde von Thore am 31.12.2011 um 12:20 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

03.01.2012, 11:54 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Thore:
Kommt drauf an was Du anforderst. Ich hab hier im Demo ED_TYPE verwendet, das reicht mir für die Anzahl.

Da hast Du etwas grundsätzliches nicht verstanden. Der Name ist immer im Ergebnis enthalten. Gibst Du ED_TYPE an, bekommst Du Name und Type. Gibst Du ED_SIZE an, bekommst Du Name, Type und Size. Gibst Du ED_PROTECTION an, bekommst Du Name, Type, Size und Protection. Usw.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.01.2012, 11:56 Uhr

Holger
Posts: 8116
Nutzer
@AGSzabo:
Es gibt keinen schnellen Weg. Gerade da, wo es langsam ist (OFS/FFS ohne DirCache) ist auch das Ermitteln der Anzahl langsam. Ich würde trotzdem ExAll und nicht Examine/ExNext benutzen.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.01.2012, 13:35 Uhr

Thore
Posts: 2266
Nutzer
> Da hast Du etwas grundsätzliches nicht verstanden.
Danke für die Korrektur

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 11:23 Uhr

AGSzabo
Posts: 1663
Nutzer
Ich habe gerade ExAll() ausprobiert, aber egal ob ich ExAll() oder ExNext() verwende, das UAE System friert bei großen Directorys, so ab ca 1000 einträge beim ERSTEN Aufruf der Funktion deutlich sicht- und spürbar ein. Also bei mir hier. Beim ASL Requester passiert das aber nicht. ?

ps: und Examine() / ExNext() scheint schneller zu sein.

--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ Dieser Beitrag wurde von AGSzabo am 04.01.2012 um 12:03 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 15:22 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von AGSzabo:
Ich habe gerade ExAll() ausprobiert, aber egal ob ich ExAll() oder ExNext() verwende, das UAE System friert bei großen Directorys, so ab ca 1000 einträge beim ERSTEN Aufruf der Funktion deutlich sicht- und spürbar ein. Also bei mir hier. Beim ASL Requester passiert das aber nicht. ?

Da musst Du wohl mal ein bisschen konkreter werden.

Mit welchen Typen von Datenträger hast Du denn getestet? Hardfile, native Directory, RAM Disk…

Bzw. mit welchen Dateisystemen, FFS, SFS, ect.
Zitat:
ps: und Examine() / ExNext() scheint schneller zu sein.
Vielleicht mit Deiner Vorgehensweise. Wenn Du zwischen den beiden einen spürbaren Unterschied feststellen kannst, stimmt offensichtlich etwas nicht.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 15:23 Uhr

Thore
Posts: 2266
Nutzer
Was hast Du denn als Buffergröße für ExAllControl eingestellt?

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 16:24 Uhr

AGSzabo
Posts: 1663
Nutzer
Der UAE greift auf meine linuxseitig native Platte zu. buffergröße war zum testen so das genau 1 eintrag mit voller datei- und kommentarlänge rein passt. wenn ich mehr nehme, würde ich mein ganzes schönes Refresh auf ticks basis sabotieren? eine schleife hab ich trotzdem gemacht, da bei kurzem dateinamen auch zwei oder mehr files in meinen buffer passen. vielleicht sollte ich einen größeren buffer wählen, aber hey, das stört mich garnicht so. vielmehr nur dieses vorrübergehende einfrieren.

ps: Der Flaschenhals ist definitiv das Einfügen der richtigen Position, nicht das einlesen von disk. Im ersten Moment sind gleich 1000 files gelesen, dann wird es immer langsamer. Mit ExAll() und einem größeren Buffer ließe sich das IMO auch nicht weiter beschleunigen.

--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ Dieser Beitrag wurde von AGSzabo am 04.01.2012 um 16:26 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 17:11 Uhr

Thore
Posts: 2266
Nutzer
Mit einem größeren Buffer könnte aber deine Durchlaufzeit kleiner werden... auch an Effizienz denken :) Und wenn dein Mainloop nur alle 40 Dateien tickt, wenn Du sagst in einem kurzen Moment sind 1000 Dateien geladen, ist das ausreichend schnell.
1 finde ich für zu wenig.

Warum bricht es denn ein, Ist es die Such-Routine fürs Einfügen?

[ Dieser Beitrag wurde von Thore am 04.01.2012 um 17:12 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 17:41 Uhr

AGSzabo
Posts: 1663
Nutzer
@Thore:

Die Suchroutine braucht immer länger je mehr Einträge vorhanden sind.

Außerdem grast der Refresh und Re-Layout immer alle vorhandenen Objekte ab, ob eines geupdated werden will, ja und zwar rekursiv für Kinder und Kindeskinder usw. Gezeichnet wird aber nur, was auch sichtbar ist.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 17:49 Uhr

Thore
Posts: 2266
Nutzer
ok ist es mit Sicherheit die Such-Routine oder vielmehr der Refresh?
Wie suchst du denn? Vollstrings oder intelligent? Also Anfangsbuchstabe, dann 2. Buchstabe, etc?

Wenn Du auf Interpolationssuche umswitchst, wirds dann besser?

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 17:59 Uhr

AGSzabo
Posts: 1663
Nutzer
@Thore:

Wenn ein Buchstabe nicht gleich ist, wird gleich abgebrochen:

code:
.strcmp		; a0 string1, a1, string2

		moveq  #0,d0
		moveq  #0,d1
.loop1		move.b  (a1)+,d1
		bclr	#5,d1	; case independent
		move.b  (a0)+,d0
		beq.s  .exit1
		bclr	#5,d0
		cmp.b  d0,d1
		beq.s  .loop1
.exit1		sub.l  d1,d0
		rts


Der Refresh ist es nicht, ich habe ihn eben mal ausgeschaltet und die Sekunden gezählt, es macht keinen Unterschied.

Ich weiss nicht, wie man eine Interpolationssuche macht.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 18:39 Uhr

Thore
Posts: 2266
Nutzer
Checkst du hier nur String1 auf das String-Ende? Was ist wenn String2 vorher aufhört?

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 18:44 Uhr

AGSzabo
Posts: 1663
Nutzer
@Thore:

ich hab diese Routine von jemand aus dem Forum hier. Es war ein ganzer bubblesort Algo. Der fehlende Check ist mir auch schon aufgefallen, ich dachte aber, das macht nichts, ist evtl auch schneller so.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:13 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von AGSzabo:
Der UAE greift auf meine linuxseitig native Platte zu.

Und wann testest Du es auch mal mit anderen Laufwerken?
Zitat:
buffergröße war zum testen so das genau 1 eintrag mit voller datei- und kommentarlänge rein passt.
Und dann kommst Du zur Erkenntnis, dass ExNext im Vergleich dazu schneller ist… nachdenken könnte manchmal etwas helfen.
Zitat:
wenn ich mehr nehme, würde ich mein ganzes schönes Refresh auf ticks basis sabotieren?
Wieso sollte es? Du willst doch wohl nicht max. 10 Dateien pro Sekunde einlesen, oder?
Zitat:
ps: Der Flaschenhals ist definitiv das Einfügen der richtigen Position, nicht das einlesen von disk. Im ersten Moment sind gleich 1000 files gelesen, dann wird es immer langsamer.
Wie jetzt, wird nun das Einlesen langsamer oder der „Flaschenhals“ des Einfügens, der auch für die ersten 1000 Files 1000 mal ausgeführt werden muss?

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:26 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

Das Einfügen ist der Flaschenhals. Ganz eindeutig und geprüft. Wie macht man eine Interpolationssuche?
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:28 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von AGSzabo:
Der fehlende Check ist mir auch schon aufgefallen, ich dachte aber, das macht nichts, ist evtl auch schneller so.

Warum sollte es schneller sein, Speicherbereiche, die gar nicht mehr zum String gehören, zu vergleichen?

Man muss an der Stelle deshalb nicht auf null testen, weil die Schleife in jedem Fall beendet wird: entweder ist der andere String an der Stelle auch null, dann wird abgebrochen oder er ist ungleich, dann wird ebenfalls abgebrochen.

Man sollte aber schon verstanden haben, was der Code tut, den man benutzt.

Andere Frage, was ist hiermit:
Zitat:
Original von AGSzabo:
Das Directory hat 2000 Files und es geht jetzt mit der sequentiellen Suche berauschend schnell.

Warum ist es jetzt plötzlich schon ab 1000 Files nicht mehr schnell genug?

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von AGSzabo:
Wie macht man eine Interpolationssuche?


http://de.wikipedia.org/wiki/Interpolationssuche

oder

http://bit.ly/yIHET7

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:33 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

"berauschend schnell" war der erste eindruck. inzwischen ist es mir nimmer schnell genug.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:40 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

> http://de.wikipedia.org/wiki/Interpolationssuche

Aha. Also für den Wahlfreien Zugriff fehlt mir der Index. Ich habe eine verkettet Liste. Wäre es möglich, einen Index zu horten? IMO würde das Updaten von diesem eher noch viel mehr Zeit benötigen.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:44 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

> Warum sollte es schneller sein, Speicherbereiche, die gar nicht mehr zum String gehören, zu vergleichen?

Tut ja keiner, oder?
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 20:50 Uhr

Thore
Posts: 2266
Nutzer
ah klar, ist String 2 kürzer, wird $0 mit nem Buchstaben verglichen -> Abbruch
Ist String 1 kürzer findet er $0 -> Abbruch
Sind beide Strings gleich lang findet er von String 1 die $0 -> Abbruch

Code zweimal lesen, dann kommt man drauf ;)

[ Dieser Beitrag wurde von Thore am 04.01.2012 um 20:50 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 21:32 Uhr

AGSzabo
Posts: 1663
Nutzer
Wow! Ich habe es nochmal enorm beschleunigen können:

- die Listview ist ein Objekt, welches das Listrow Objekt in der Vielzahl benutzt.

- beim sortierten Adden hat die Listview bisher immer den Text und die Priorität der Zeilen per GetAttr() aus den Listrow Objekt gelesen. Das bedeutet, es geht bei jeder schon vorhandenen Zeile immer durch ihren Dispatcher!

- jetzt habe ich der Listrow zwei weitere Attribute hinzugefügt, die man mit GetAttr() auslesen kann: den Offset zum Textzeiger im Objekt und den Offset zum Prioritätswert.

- die Listview holt sich jetzt beim Adden der neuen Zeile von dieser mal eben diese beiden Offsets, und liest dann mit deren Hilfe den Text und die Priorität der schon vorhandenen Zeilen aus!
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 21:35 Uhr

Thore
Posts: 2266
Nutzer
> die Listview holt sich jetzt beim Adden der neuen Zeile von dieser mal eben diese beiden Offsets, und liest dann mit deren Hilfe den Text und die Priorität der schon vorhandenen Zeilen aus!

Öhm ich dachte das wird bereits so gemacht :D Weil relative Objekte in der Regel das Offset des Vorgängers benutzen.
Aber schön wenn du hier optimieren konntest :)

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 21:39 Uhr

AGSzabo
Posts: 1663
Nutzer
@Thore:

Welches ist das relative Objekt? Die Listview benutzt den Offset der Row. Die Row ist der Vorgänger, weil die Liste drauf auf baut? In meinem Fall kann man sich auch in diesem Fall nicht auf die Offsets verlassen. Daher werden sie geholt.
--
Author of Open eXternal User Interfaces, eXternal Format Rippers and the Book "Torakosmos". Developing with E-UAE on an Ubuntu dualcore system.

[ - Antworten - Zitieren - Direktlink - ]

04.01.2012, 21:40 Uhr

Thore
Posts: 2266
Nutzer
ich meinte relativ anhand der Position. Also die Listen-Einträge. Deine Rows.

[ Dieser Beitrag wurde von Thore am 04.01.2012 um 21:41 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.01.2012, 12:29 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von AGSzabo:
> Warum sollte es schneller sein, Speicherbereiche, die gar nicht mehr zum String gehören, zu vergleichen?

Tut ja keiner, oder?

Das wusstest Du aber nicht. Trotzdem hast Du angenommen, dass es schneller wäre.

Zitat:
Original von AGSzabo:
Also für den Wahlfreien Zugriff fehlt mir der Index. Ich habe eine verkettet Liste. Wäre es möglich, einen Index zu horten?

Einen Index horten?

Du brauchst keinen Index, sondern die umgekehrte Operation: für eine gegebenen Index den richtigen Knoten finden.

Das ist trivial. Um einen Knoten mit Index x zu finden, initialisierst Du Deinen Variable mit dem Head-Knoten und ersetzt ihn dann x-Mal durch seinen next-Zeiger.

Wenn Du Dir den Knoten und seinen Index in den Zwischenschritten merkst, kannst Du auch diesen als Ausgangsbasis benutzen, um zum nächsten Index zu gelangen, in dem Du die Differenz vor oder zurück gehst.

Bei der Binären Suche ergeben sich dabei folgende Iterationen:
n/2 Schritte vor
n/4 Schritte vor oder zurück
n/8 Schritte vor oder zurück
n/16 Schritte vor oder zurück
n/32 Schritte vor oder zurück
usw.

Offensichtlich musst Du in diesem Fall exakt n viele next/prev Pointer auslesen, d.h. so viele wie bei der linearen Suche im worst case. Dafür musst Du aber deutlich weniger Strings vergleichen. Das bringt bei vielen ähnlichen Strings einen deutlichen Schub. Andererseits frag ich mich immer noch, wo da die Zeit verbraten werden soll, bei 2000 Einträgen und dem gezeigten Assembler-Code.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 3 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Wieviele Files in Dir? [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.