Aufgabe 2


fgets ist gut, aber scanf naja ich weiss nicht ob das so wirklich das wahre ist?


Das „Problem“ was du hast lässt sich aber relativ leicht umgehen.
Ich weiß zwar auch nicht, ob jetzt getchar() oder fgets() schneller ist, würde aber gerade beim Einlesen aus einer Datei auf fgets() tippen. Hab allerdings keine Ahnung, wie dem wirklich ist, also falls jemand besser bescheid weiß…?

Und jetzt noch eine Frage:
Kann ich davon ausgehen, dass vor einem jedem EOF ein ‚\n‘ steht, d.h. ein EOF immer direkt nach einem Zeilenumbruch folgt?
D.h. sich direkt vor einem EOF sicher keine Zeichen mehr befinden?
Bei Eingabe in der Shell bzw. der Windows Konsole wird ja genau das erreicht, da lässt sich ein Strg+D bzw. ein Strg+Z nur direkt nach einem Zeilenumbruch unterbringen.
Aber wie schaut das aus beim Einlesen von Dateien? Wenn ich jetzt halt eine Datei auf meine Standarteingabe umleite? Wäre da sehr dankbar, wenn da jemand kompetentes Wissen dazu hätte :wink:

Würde im Endeffekt halt pro Zeile/Wort eine Abfrage, und damit ein wenig Zeit, sparen, deswegen die Frage. Weil langsam geht nicht mehr weniger :wink:

Edit: Okay, hat sich geklärt. Man kann nicht davon ausgehen. In einer Datei bekommt man natürlich zwischen das „letzte“ \n und EOF auch noch Zeichen dazwischen.


schön das du weisst wie :zzz: … hab da jetzt ne stunde rumgebastelt, aber keine ahnung. egal mit getchar funktionierts zumindest auch ^^

andere frage, wieviel speicher reserviert ihr jeweils vor für die zeiger die auf die anfaenge zeigen? also ich reservier immer 1000 und erweiter dann beim 1000ten wieder um 1000 usw… oder ist das im sinne der geschwindigkeit eher irrelevant?

edit: ohne fehlerabfragen komme ich jetzt inzwischen auf

$time ./wsort < /proj/i4sos/pub/aufgabe2/wlist4 > /dev/null
1.851u 0.067s 0:01.92 99.4% 0+0k 0+0io 0pf+0w


Naja, wenn dus schon geschafft hast zu lange Wörter herauszufiltern, dann tu doch einfach sobald du ein derartiges Wort gefunden nicht in deine nächste Schleife einsteigen um das nächste Wort zu suchen, sondern mach erst derweilen die jetzige Zeile „leer“, d.h. geh einfach ohne dir zu merken was du zurückbekommst bis zum nächsten ‚\n‘ bzw. EOF.


jo so hab ich auch gedacht, aber was geb ich der fgets funktion dann als 2.argument … gibt ja kein unendlich oder so, dass ich sichergehen kann dass er auch bis zum zeilenende geht, oder gibt es eine maximal-zeilenlänge die man nicht überschreiten kann? 255 vll :X ? dunno


Wer sagt, dass du in solchen Fällen beim „ans Ende der Zeile gehen“ fgets und nicht in dem Fall vielleicht doch lieber getchar nehmen sollst? … :wink:
Wobei das auch mit einem fgets, einem Dummy-String-Buffer und einer Schleife gehen müsste.


:stuck_out_tongue: oke oke :slight_smile: hast ja recht … thx dennoch. ich merke dennoch kein unterschied der geschwindigkeit, aber das liegt wohl eher an meinem unbedarften programmierstil 8-(


Es reicht denk ich auch einfach das ganze 2-3x zu starten. Der erste Aufruf dauert i.d.R. doppelt so lang, danach liegen die Dateien im RAM und die darauffolgenden Aufrufe sind alle vergleichbar schnell. Scheint also nicht das Problem zu sein, oder können die NFS mounts immer noch dazwischen funken?


Paar Dinge für alle Benchmarkwilligen :slight_smile:

[list]
[]Demnächst ist fsort online, dass allerdings auf Dateien arbeitet.
[
]Zum Benchmarken - sach ich etz einfach mal so, am einfachsten:
[list]
[]Auf faui05 starten
[
]Alle Compilerswitches sind erlaubt
[*]Die Kommandozeile zum testen: (Vorrausgesetzt ihr seid im richtigen ordner, bash als shell): time ./wsort < ../../../pub/aufgabe2/wlist4 > /dev/null
[/list]
[/list]

Ergebnis bei mir:

[code]@faui05:/proj/i4sos/simachaj/aufgabe2/bin.i386 # time ./wsort < …/…/…/pub/aufgabe2/wlist4 > /dev/null

real 0m0.958s
user 0m0.912s
sys 0m0.030s

[/code]


[code]faui05 [~/wsort/bin.i386]> for list in /proj/i4sos/pub/aufgabe2/wlist*; do echo $list; time ./wsort < $list > /dev/null; done
/proj/i4sos/pub/aufgabe2/wlist0

real 0m0.002s
user 0m0.001s
sys 0m0.001s
/proj/i4sos/pub/aufgabe2/wlist1

real 0m0.015s
user 0m0.015s
sys 0m0.000s
/proj/i4sos/pub/aufgabe2/wlist2

real 0m0.029s
user 0m0.027s
sys 0m0.003s
/proj/i4sos/pub/aufgabe2/wlist3

real 0m0.189s
user 0m0.177s
sys 0m0.009s
/proj/i4sos/pub/aufgabe2/wlist4

real 0m0.897s
user 0m0.853s
sys 0m0.035s[/code]

Mit lokalen Dateien sieht das ganze noch ein bisschen besser aus:

[code]faui05 [~/wsort/bin.i386]> for list in /var/tmp/whoami/wlist*; do echo $list; time ./wsort < $list > /dev/null; done
/var/tmp/sigubeut/wlist0

real 0m0.002s
user 0m0.000s
sys 0m0.000s
/var/tmp/sigubeut/wlist1

real 0m0.016s
user 0m0.013s
sys 0m0.003s
/var/tmp/sigubeut/wlist2

real 0m0.027s
user 0m0.025s
sys 0m0.003s
/var/tmp/sigubeut/wlist3

real 0m0.191s
user 0m0.175s
sys 0m0.013s
/var/tmp/sigubeut/wlist4

real 0m0.720s
user 0m0.686s
sys 0m0.032s
/var/tmp/sigubeut/wlist4-sorted

real 0m0.009s
user 0m0.006s
sys 0m0.003s[/code]

An der Datei “wlist4-sorted” sieht man schön, dass die Performance des ganzen Programms sehr stark von “qsort” abhängt.

Mfg,
shroud


Hah, in your face!
[m]/proj/i4sos/pub/aufgabe2/wlist4
-bash: ./wsort: No such file or directory

real 0m0.001s
user 0m0.000s
sys 0m0.000s[/m]

Nein, Schmarrn… das echte Ergebnis sieht so aus, und wenn der Anteru nicht schon eine Runde Vorsprung hätte… :smiley:
[m]real 0m1.021s
user 0m0.998s
sys 0m0.023s[/m]


Hallo…

Es geht mir jetzt nicht direkt um die Zeit, aber wie muss ich das interpretieren???

 time ./wsort < /proj/i4sos/pub/aufgabe2/wlist4 > /dev/null
1.858u 0.108s 0:02.42 80.5%     0+0k 0+0io 0pf+0w

Ach ja, und noch was, zu euerer Benchmarkerei:
Was passiert, wenn sich zufälligerweise während eures Aufrufs von wsorts, von extern auf eurem PC noch jemand einloggt und zufälligerweise auch noch z.b. wsort ausführt? Wer bekommt denn dann die Systemresourcen? Werden dann die Messzeiten nicht gravierend verfälscht? :wink:


real 0.711s und jetzt geh ich schlafen - genug für heute
shroud lag vor 1minute bei 0.712 was ich mal darauf zurückführe das jemand den PC angehaucht hat oder so.


“vielleicht”:

1.858u heisst, dass das Programm 1.858 Sekunden im Userspace verbracht hat
0.108s: 0.108 Sekunden im Kernel
80.5% der Zeit wurde in User-Code verbracht

Die restliche Ausgabe kann ich nicht entziffern.

Mfg,
shroud


Gravierend verfaelscht wird nur die Realtime. Die anderen Zeiten sind die addierten Zeiten, in denen wirklich dein Prozess den Prozessor zu seiner Verfuegung hat, aufgeteilt in usermode (das ist ‚normaler‘ code, den ihr geschrieben habt) und systemmode (das sind die ausfuehrungszeiten von syscalls, die das BS ja fuer euch erledigt). Einige Effekte lassen sich jedoch schon bemerken, wenn z.B. der Prozess laenger am Stueck laufen kann, dann kann er caches effizienter ausnutzen. Von daher sind die nie 100% miteinander vergleichbar. Allerdings sollten sich diese Effekte auch rausmitteln, weil ja alle in der Umgebung arbeiten, man sollte halt mal gucken, ob an ‚seinem‘ Rechner nicht grad ne Simulation von jemand anders laeuft - am Ende gar ein wsort :slight_smile:

Achja - das ‚time‘ kommando gibts uebrigends in 2 Ausfuehrung, als shell feature und als eigenstaendiges Programm, letzteres wird als /usr/bin/time ./wsort … aufgerufen, ansonsten erwischt ihr das shell aequivalent. Was ihr nehmt sollte egal sein, aber die Ausgaben sind halt anders.


Wo bleibt denn eigentlich fsort?
Weiß da jemand was?
Wäre mal interessant damit zu vergleichen.


[m]fsort[/m] und [m]wlist5[/m] sind jetzt in [m]/proj/i4sos/pub/aufgabe2[/m] verfügbar.


Endlich, darauf haben wir doch nur gewartet :wink:

Ich benutze keine Sonderbehandlung für den Fall, dass ich eine Datei bekomme und kopiere dann einfach alles auf einmal in ein passend großes Array. Bei meinem Programm ist Stream gleich Stream, d.h. ein Ende merke ich nur indem ich dort ankomme und mir ein EOF signalisiert wird.
Ich benutze auch keine Threads und damit auch keine Multithreading whatsoever. Alles total “normales simples” C Programm.
Ich benutze auch keine eigene Sortierfunktion, ich verwend genauso qsort (ich denk sowieso qsort ist schon nahezu, wenn nicht sogar komplett perfekt implementiert).

Ansonsten hab ich natürlich genug Kniffe und dergleichen eingebaut :wink:

Zusätzliches Compilerflag -O3
Ich hab die Dateien nicht lokal liegen, ich lade wie man sieht nach wie vor von /proj/i4sos/pub/aufgabe2/wlist*
Getestet hab ich mal auf faui08, da ist meistens wenig los, d.h. man bekommt stabile Zeiten (faui05 ist zwar schneller, also die Zeiten meines wsort und auch die von fsort sind nochmal tiefer, aber auf faui05 bekomm ich gerade keine stabilen Zeiten daher):

faui08 [aufgabe2]> make time
time src/wsort </proj/i4sos/pub/aufgabe2/wlist4 >/dev/null

real    0m0.577s
user    0m0.554s
sys     0m0.023s
time /proj/i4sos/pub/aufgabe2/fsort </proj/i4sos/pub/aufgabe2/wlist4 >/dev/null

real    0m0.840s
user    0m0.814s
sys     0m0.024s

time src/wsort </proj/i4sos/pub/aufgabe2/wlist5 >/dev/null

real    0m1.119s
user    0m1.061s
sys     0m0.042s

time /proj/i4sos/pub/aufgabe2/fsort </proj/i4sos/pub/aufgabe2/wlist5 >/dev/null

real    0m1.580s
user    0m1.537s
sys     0m0.041s

Yeah, 30% schneller :smiley:
Na da geht aber doch wohl noch was bei fsort? :wink:

Und ja, mein Programm liefert noch die korrekte Ausgabe :stuck_out_tongue_winking_eye: (Da vergisst man zu überprüfen. Dann optimiert man wie wild und plötzlich merkt man, dass die Ausgabe gar nicht mehr stimmt)


[s]wieso bekomm ich die zeiten immer als

1.858u 0.108s 0:02.42 80.5%     0+0k 0+0io 0pf+0w

und ihr als:

real 0m1.580s user 0m1.537s sys 0m0.041s [/s]

ps: /me is linux noob :slight_smile:

@TheChip: ist mir gerade aufgefallen als ichs in die Makefile geworfen hab :smiley:


Ich bin auch Linux noob und hab mich das dauernd gefragt, bis ich zufällig drauf gestoßen bin:
Wenn ich per Putty ssh direkt per Hand eingebe “time wsort …”
dann bekomm ich auch so ne einzeilige Ausgabe

aber wenn du dir in dein Makefile was schreibst ala:

time:
time wsort …

und dann “make time” eintippst, dann bekommst du die andere Ausgabe.
Zumindest ich hier per Putty ssh.