Effizient mehrere Zeichen ausgeben

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Effizient mehrere Zeichen ausgeben

Beitrag von JTH » 09.05.2019 13:13:51

Meillo hat geschrieben: ↑ zum Beitrag ↑
09.05.2019 12:27:54
[…] impliziten Regeln der alten C-Varianten […]
Ganz strenggenommen fehlt der C89-Variante noch ein return 0; in main(). Das ist mein ich umgekehrt erst ab C99 implizit, wenn ausgelassen. Aber genug Standard gewälzt :)
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Effizient mehrere Zeichen ausgeben

Beitrag von Meillo » 09.05.2019 13:28:05

JTH hat geschrieben: ↑ zum Beitrag ↑
09.05.2019 13:13:51
Meillo hat geschrieben: ↑ zum Beitrag ↑
09.05.2019 12:27:54
[…] impliziten Regeln der alten C-Varianten […]
Ganz strenggenommen fehlt der C89-Variante noch ein return 0; in main(). Das ist mein ich umgekehrt erst ab C99 implizit, wenn ausgelassen. Aber genug Standard gewälzt :)
Darum habe ich ``-pedantic'' weggelassen. :-P

Aber ja, genug des Geplaenkels ... eigentlich warten doch alle bloss auf heinz. ;-)
Use ed once in a while!

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Effizient mehrere Zeichen ausgeben

Beitrag von heinz » 09.05.2019 23:33:13

Klasse! Ich bin sehr froh, nicht der einzige verrueckte hier zu sein... ;-) (Ich liebe dieses Forum...)

Vielen Dank erstmal fuer die sehr kreativen Vorschlaege!
niemand hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 21:30:50
gcc zählt doch auch zu den Bordmitteln …
Naja, da hast Du sicher recht. Habe auch ein kleines C-Programm dafuer geschrieben aber es dann wieder verworfen.
In scripten moechte lieber keine Programme verwenden die auf einem anderen System erst "gebaut" werden muessen.

Wobei ich zugeben muss, der Einzeiler von JTH ist echt super! Ich waere nie auf die Idee gekommen gcc so zu benutzen.

Meillo hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 22:00:46
Viel schneller ist ``bs=100000 count=1''. ;-) Ich bin mir fast sicher, dass das gewinnen wird. Da bremst nur noch die Terminalausgabe.
Du hast recht und das gibt dann auch den neuen Platz 1!
Meillo hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 22:00:46
Btw: Wie testest du die Zeiten denn? Da sollte man wohl viele Messungen machen, die Extremwerte weglassen und den Rest mitteln.
Ich lasse es so ca. 20 mal laufen und merke mir die hoechsten und niedrigsten Werte.
Die Extremwerte lasse ich natuerlich weg aber mitteln tu ich nicht...
(vlt. sollte ich dafuer ein kleines Script schreiben... Mal schauen wie ich lustig bin...)


Hier nun die neuen Testergebnisse:

Platz 1 (Tipp von Meillo)

Code: Alles auswählen

time yes \#|tr -d '\n'|dd bs=100000 count=1

real 0.006 - 0.015
user 0.000 - 0.000
sys  0.000 - 0.004
Wobei ich nicht verstehe, warum

Code: Alles auswählen

dd bs=1 count=100000 </dev/zero 2>/dev/null | tr \\0 \#
langsamer ist?


Platz 2 (RobertDebiannutzer) (scheint gleichschnell zu sein wie der vorherige Platz 1)

Code: Alles auswählen

perl -e 'print "#"x100000'
oder
perl -e 'print "#"x100000'

real 0.017 - 0.026
user 0.000 - 0.004
sys  0.000 - 0.004
Platz 3 (RobertDebiannutzer) (knapp aber hoehere Werte bei user)

Code: Alles auswählen

awk 'BEGIN{ while (n++ < 100000) printf "#" }' 

real 0.018 - 0.021
user 0.004 - 0.016
sys  0.000 - 0.004
Platz 4 (Meillo) (etwas besser als der vorherige Platz 3)

Code: Alles auswählen

dd bs=1 count=100000 </dev/zero 2>/dev/null | tr \\0 \#

real 0.047 - 0.063
user 0.004 - 0.024
sys  0.072 - 0.104
Platz 5 (tobo)

Code: Alles auswählen

printf %.s# {1..100000}

real 0.177 - 0.187
user 0.160 - 0.172
sys  0.000 - 0.004
Ist irgendwie auch seltsam. Warum ist das so langsam?

Nochmals vielen Dank Euch allen!
Meillo hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 22:00:46
Ach, und machen wir nebenbei oder hinterher auch noch ein ``Wer loest es mit der kuerzesten Befehlszeile''? Biiiiiitte-biiiitte! :-D
*Lach*, aber da wird wohl schon tobo gewonnen haben. Ich denke kuerzer als:

Code: Alles auswählen

printf %.s# {1..100000}
wird wohl nicht moeglich sein... (Schade das es so langsam ist.)

Viele Gruesse, heinz

Benutzeravatar
hikaru
Moderator
Beiträge: 13585
Registriert: 09.04.2008 12:48:59

Re: Effizient mehrere Zeichen ausgeben

Beitrag von hikaru » 10.05.2019 00:55:03

Vielleicht nicht effizient, aber Brainfuck [1]:

Code: Alles auswählen

--[------->++<]>-
>++++++++++[
 >++++++++++[
  >++++++++++[
   >++++++++++[
    <<<<.>>>>
   -]<
  -]<
 -]<
-]
Natürlich ist das nicht auf meinem Mist gewachsen. Ich hab's nur mühselig zusamengestückelt.
- # von [2]
- Idee für die Schleife von [3]
- Test auf [4] (lässt sich lokal vermutlich durch Debianhsbrainfuck ersetzen)

Sollte Assembler nicht schnell sein?


[1] https://de.wikipedia.org/wiki/Brainfuck
[2] https://copy.sh/brainfuck/text.html
[3] https://stackoverflow.com/questions/454 ... print-loop
[4] https://copy.sh/brainfuck/

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Effizient mehrere Zeichen ausgeben

Beitrag von Meillo » 10.05.2019 08:18:30

heinz hat geschrieben: ↑ zum Beitrag ↑
09.05.2019 23:33:13
Klasse! Ich bin sehr froh, nicht der einzige verrueckte hier zu sein... ;-) (Ich liebe dieses Forum...)
:-)
Ich lasse es so ca. 20 mal laufen und merke mir die hoechsten und niedrigsten Werte.
Die Extremwerte lasse ich natuerlich weg aber mitteln tu ich nicht...
(vlt. sollte ich dafuer ein kleines Script schreiben... Mal schauen wie ich lustig bin...)
Kannst dir ja mal ueberlegen, ob rueckblickend das Schreiben eines Scriptes nicht schneller gewesen waere als all die manuellen Programmaufrufe, die du bisher gemacht hast. Der Vorteil am Script ist, dass du zum einen, falls du einen Fehler im Vorgehen entdeckst, einfach alle Tests nochmal laufen lassen kannst, und zum zweiten, dass es keinen Mehraufwand verursacht, wenn du statt 20 lieber 200 Durchlaeufe machen willst.

Hier nun die neuen Testergebnisse:

Platz 1 (Tipp von Meillo)

Code: Alles auswählen

time yes \#|tr -d '\n'|dd bs=100000 count=1

real 0.006 - 0.015
user 0.000 - 0.000
sys  0.000 - 0.004
Da stimmt die Codezeile noch nicht, oder haben wir uns falsch verstanden?

Ich denke, am schnellsten waere:

Code: Alles auswählen

dd bs=100000 count=1 </dev/zero 2>/dev/null | tr \\0 \#
... und nicht eine Variante mit yes(1).
Wobei ich nicht verstehe, warum

Code: Alles auswählen

dd bs=1 count=100000 </dev/zero 2>/dev/null | tr \\0 \#
langsamer ist?
`bs=1 count=100000' liest 100.000 Mal ein Byte, waehrend `bs=100000 count=1' ein Mal 100.000 Bytes liest. Der ganze Leseoverhead (Festplatten-Seek & Co.) sind dann nur einmal und nicht potenziell 100.000 Mal vorhanden.

Das ist wie wenn du aus einem Buch 100.000 Zeichen am Stueck liest, im Gegensatz dazu, das Buch aufzuschlagen, ein Zeichen zu lesen, es zuzuschlagen, es wieder aufzuschlagen, die Stelle zu finden, das naechste Zeichen zu lesen, es wieder zuzuschlagen, usw.

Platz 5 (tobo)

Code: Alles auswählen

printf %.s# {1..100000}

real 0.177 - 0.187
user 0.160 - 0.172
sys  0.000 - 0.004
Ist irgendwie auch seltsam. Warum ist das so langsam?
Weil die Shell hier bei der Brace-Expansion eine riesig lange Befehlszeile erzeugen muss, die sicherlich mehrere realloc(3)s benoetigt und vielleicht noch weiteren Overhead erzeugt. Das printf(1) (oder das Shell-Builtin printf?) muss dann fuer seinen Output-Buffer wieder mehrmals Reallozieren. Da wird also immer wieder im Speicher rumkopiert. Das wird es vermutlich langsam machen.
Meillo hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 22:00:46
Ach, und machen wir nebenbei oder hinterher auch noch ein ``Wer loest es mit der kuerzesten Befehlszeile''? Biiiiiitte-biiiitte! :-D
*Lach*, aber da wird wohl schon tobo gewonnen haben. Ich denke kuerzer als:

Code: Alles auswählen

printf %.s# {1..100000}
wird wohl nicht moeglich sein... (Schade das es so langsam ist.)
Das scheint mir auch so zu sein. Auch die Umsetzung in C wird wohl kaum noch kuerzer gehen. (Das letzte Mal, als ich so eine Vermutung geaeussert habe, hat tobo direkt eine kuerzere Version gepostet ... vielleicht klappt das dieses Mal wieder. ;-) )
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Effizient mehrere Zeichen ausgeben

Beitrag von RobertDebiannutzer » 10.05.2019 09:46:50

"Brainfuck" kann ich auch... :mrgreen:

Code: Alles auswählen

str="" && while [ $(wc -m <<< $str) -lt 100000 ]; do str+=$(openssl rand 100000 | grep -o --text '#' | tr -d '\n'); done && printf $str
(Erfordert bash und openssl-rand. Die Anforderung von 100000 Zufalls-Bytes ist natürlich beliebig.) Das gibt zwar stets mehr als 100000 "#" aus, aber es waren ja auch nicht *genau* 100000 gefordert:
heinz hat geschrieben: ↑ zum Beitrag ↑
08.05.2019 19:52:01
Testbedingungen:
100000 mal das Zeichen >#< ausgeben. (Hintereinander. Keine weiteren Zeichen!)
( 100000 um einigermassen sinnvolle Zeiten zu bekommen. )
*SNCR*
Meillo hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 08:18:30
(oder das Shell-Builtin printf?)
In bash (Debian stretch) ist es ein builtin. In dash auch. @heinz: Mit "type builtin" kannst Du es herausfinden, jedenfalls bei den beiden genannten Shells.

Mit gcc ging es kürzer, wenn stdio.h nicht includiert ( :wink: ) werden müsste:

Code: Alles auswählen

gcc -xc -<<<$'#include<stdio.h>\nmain(){printf("%*c",100000,\'#\');}';./a.out

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Effizient mehrere Zeichen ausgeben

Beitrag von Meillo » 10.05.2019 10:38:17

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 09:46:50
Mit gcc ging es kürzer, wenn stdio.h nicht includiert ( :wink: ) werden müsste:

Code: Alles auswählen

gcc -xc -<<<$'#include<stdio.h>\nmain(){printf("%*c",100000,\'#\');}';./a.out
Hast du das getestet? Bei mir gibt das keine 100.000 Hashes aus, sondern 99.999 Spaces gefolgt von einem Hash.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Effizient mehrere Zeichen ausgeben

Beitrag von RobertDebiannutzer » 10.05.2019 10:44:52

Oh Mist!! Ja, ich habe es getestet, aber nur mit "wc -m" - der Output ging also in die Pipe zu wc und somit habe ich ihn nicht gesehen. :facepalm:
Aber ich bin mir fast sicher, dass das mit printf() irgendwie ging. Nur ich finde grad nix dazu in der manpage und suchmaschinen will ich natürlich nicht (das gilt ja nicht :wink: ).

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Effizient mehrere Zeichen ausgeben

Beitrag von Meillo » 10.05.2019 10:57:41

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 10:44:52
Oh Mist!! Ja, ich habe es getestet, aber nur mit "wc -m" - der Output ging also in die Pipe zu wc und somit habe ich ihn nicht gesehen. :facepalm:
Ich arbeite einfach mit der Zahl 100 statt 100000, damit mir der Bildschirm nicht zugemuellt wird. Nur so als Tipp. ;-)
Aber ich bin mir fast sicher, dass das mit printf() irgendwie ging.
Es geht halt so wie tobo das gemacht hat, aber das erfordert 100.000 Argumente fuer printf() (die er mittels der Brace-Expansion erzeugt).
Nur ich finde grad nix dazu in der manpage und suchmaschinen will ich natürlich nicht (das gilt ja nicht :wink: ).
Ich sehe keinen Grund fuer diese Zurueckhaltung. Ich informiere mich auch an verschiedenen Stellen und lasse mich moeglichst breit inspirieren. Und falls jemand anderes eine fertige Loesung hat, greife ich die gerne auf (und wuerdige die Person dafuer).
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Effizient mehrere Zeichen ausgeben

Beitrag von RobertDebiannutzer » 10.05.2019 11:46:24

In $Suchmaschine habe ich wieder gefunden, was ich meinte:
You can use the %* form of printf, which accepts a variable width. And, if you use '0' as your value to print, combined with the right-aligned text that's zero padded on the left..

Code: Alles auswählen

printf("%0*d\n", 20, 0);
produces:

Code: Alles auswählen

00000000000000000000
With my tongue firmly planted in my cheek, I offer up this little horror-show snippet of code.
Quelle: https://stackoverflow.com/questions/146 ... ing-printf
Aber das funktioniert leider nicht mit dem "#"-Zeichen. Und wäre so wie ich das verstehe auch echt hässlich... :mrgreen:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Effizient mehrere Zeichen ausgeben

Beitrag von JTH » 10.05.2019 12:56:00

Python 3 wäre noch eine Möglichkeit:

Code: Alles auswählen

$ time python3 -c'print("#"*100000)'

real	0m0,038s
user	0m0,033s
sys	0m0,005s
Oder Python 2 um drei Zeichen zu sparen:

Code: Alles auswählen

$ time python -c'print"#"*100000'

real	0m0,034s
user	0m0,015s
sys	0m0,016s
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Effizient mehrere Zeichen ausgeben

Beitrag von heinz » 11.05.2019 00:16:07

hikaru hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 00:55:03
Vielleicht nicht effizient, aber Brainfuck
Klasse was hier so alles auftaucht! :THX:

Meillo hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 08:18:30
Kannst dir ja mal ueberlegen, ob rueckblickend das Schreiben eines Scriptes...
Habe mir mittlerweile auch einen "zusammengezimmert". Sieht zwar schrecklich aus aber tut was es soll...
Man kann angeben wie oft ein Befehl laufen soll und die Zeiten werden dann gemittelt.
Script: NoPaste-Eintrag40711
Befehlsdatei: NoPaste-Eintrag40715
Ausgabe: NoPaste-Eintrag40716
Meillo hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 08:18:30
Da stimmt die Codezeile noch nicht, oder haben wir uns falsch verstanden?
Habe mich wohl nicht so gut ausgedrueckt.
Die Variante mit yes war schneller als nur dd. (Jetzt weis ich auch warum...)
Deshalb habe ich die an Platz 1 gezeigt.

Da habe ich uebrigens etwas seltsames bei mir festgestellt.
Mit meinem Script kann ich auch die Ausgabe testen, also ob auch wirklich die gewuenschte Menge an Zeichen ausgegeben werden.
Und:

Code: Alles auswählen

yes \#|tr -d '\n'|dd bs=100000 count=1
liefert nicht immer die gewuenschte Menge.
Es werden nur 4096, 8192, 12288, 16384 oder 20480 Zeichen ausgegeben? Wobei ich nicht feststellen/beeinflussen kann wann welche Menge kommt.
Kann das jemand reproduzieren?

Code: Alles auswählen

yes \#|tr -d '\n'|dd bs=1 count=100000
funktioniert immer korrekt.
Liefert yes moeglicherweise nicht schnell genug und dd "denkt" dann da kommt nix mehr?
Meillo hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 08:18:30
Ich denke, am schnellsten waere:
dd bs=100000 count=1 </dev/zero 2>/dev/null | tr \\0 \#
... und nicht eine Variante mit yes(1).
Da hast Du natuerlich Recht. Aber leider nur Platz 3 NoPaste-Eintrag40716
Aber einiges schneller als

Code: Alles auswählen

dd bs=1 count=100000 </dev/zero 2>/dev/null | tr \\0 \#
oder

Code: Alles auswählen

yes \#|head -n 1000000|tr -d '\n'
Meillo hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 08:18:30
printf %.s# {1..100000}
Weil die Shell hier bei der Brace-Expansion eine riesig lange Befehlszeile erzeugen muss
Alles klar, Danke fuer die Aufklaerung.

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 09:46:50
Mit "type builtin" kannst Du es herausfinden
Danke fuer den Tipp, wieder was gelernt.

JTH hat geschrieben: ↑ zum Beitrag ↑
10.05.2019 12:56:00
Python wäre noch eine Möglichkeit:
Noch eine Moeglichkeit, super.
Hab ich gleich in die Liste aufgenommen.
Liegt bis jetzt auf Platz 4 NoPaste-Eintrag40716


Die im Moment schnellste Variante scheint

Code: Alles auswählen

perl -e 'print "#"x1000000'
zu sein.
Bisherige Liste: NoPaste-Eintrag40716
(Platz 1 zaehlt nicht, da fehlerhafte ausgabe...)

Gruss, heinz

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 11.05.2019 14:18:01

Die Messungen sind grob unfair: Du misst immer nur den Zeitverbrauch der äußeren bash selbst.
Um das mal zu verdeutlichen:
Ich Poste jetzt nicht das ganze Kommando. Aber ich könnte es euch vorstellen wie es gemeint ist:

Code: Alles auswählen

time echo "##########...#######"
Braucht bei mir zwischen 0.014s und 0.017s während die yes Variante zwischen 0.023s und 0.025s braucht.
Defakto braucht ersteres eigentlich exakt 0s und lediglich mein Terminal (Konsole) ist halt so lahm, dass es die Ausgabe nicht schneller verarbeiten kann. Auf einem xterm bin ich deutlich schneller. (~0.005s)
Kurz nach deiner Messart müsste mein Kommando das rennen Gewinnen, weil es optimal ist.
Daneben sind die 10000 Zeichen halt verdammt wenig. Deswegen müssten die C-Varianten übelst abloosen, weil der gcc gar nicht schnell genug gestartet ist.
rot: Moderator wanne spricht, default: User wanne spricht.

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 11.05.2019 14:28:03

Die Messungen sind grob unfair: Du misst immer nur den Zeitverbrauch der äußeren bash selbst.
Das gilt für das neue Script im im Post vor mir nicht mehr.
rot: Moderator wanne spricht, default: User wanne spricht.

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 11.05.2019 15:52:46

Hier ein etwas erweitertes Script: pastebin/?mode=view&s=40718
* Anzahl der # kan ausgewählt werden
* Hash statt Dateigröße wird verglichen
* Deafault auf builtin time gesetzt
* mktmp genutzt.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Effizient mehrere Zeichen ausgeben

Beitrag von heinz » 11.05.2019 18:19:46

Hallo wanne
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 14:18:01
Die Messungen sind grob unfair: Du misst immer nur den Zeitverbrauch der äußeren bash selbst.
Mein bestreben war auch nicht die exakte Zeit nur des Befehls zu messen, sondern eher verwertbare Vergleichswerte zu erhalten.
Wenn alle Befehle unter den gleichen Bedingungen gestartet werden (bash + Befehl) ist das doch auch gewaehrleistet. Oder sehe ich das falsch?
Time misst doch die Zeit, wie lange die bash gelaufen ist. Und die bash beendet sich erst wenn der Befehl durch ist.
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 14:28:03
Das gilt für das neue Script im im Post vor mir nicht mehr.
Warum? Ich kann in dem Script in der Funktion zur Zeitmessung keine Aenderung finden. (Kann aber auch an mir liegen, war sehr spaet gestern... :) )
(Aber mir ist gerade aufgefallen, das ich in der Funktion "Zeit_messen" die globale Variable $befehl verwende anstatt $1...)
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 14:18:01
Deswegen müssten die C-Varianten übelst abloosen, weil der gcc gar nicht schnell genug gestartet ist.
Aber genau darum geht es doch auch. Wie lange braucht ein Befehl um auf der Konsole eine Anzahl Zeichen zu schreiben.
Wenn ein Befehl z.B. awk nutzt muss halt auch erst awk gestartet werden. Das gehoert m.M.n. zur Laufzeit dazu.

wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 15:52:46
Hier ein etwas erweitertes Script: pastebin/?mode=view&s=40718
In Zeile 30

Code: Alles auswählen

groesse_fuer_groessentest=0
noch die 0 weglassen, damit man das Script auch ohne Angabe der Zeichenmenge laufen lassen kann...
* Anzahl der # kan ausgewählt werden
Hatte ich mir auch ueberlegt aber es dann gelassen, da ich das Script auch fuer andere Zeitmessungen benutzen moechte,
bei denen es nicht um eine Ausgabe von Zeichen geht.
Z.B. Schnellere Methoden zu finden mit sdl bestimmte Grafikeffekte zu erzeugen.
Aber fuer die Augabenstellung hier ist das eine sehr gute Idee...
* Hash statt Dateigröße wird verglichen
Stimmt, so kann man auch erkennen ob auch wirklich alle Zeichen die Richtigen sind.
* Deafault auf builtin time gesetzt
Das wundert mich etwas, laut "help time" kennt bash/time die Optionen -a, -o und -f garnicht? Zeigt aber keine Fehlermeldung und funktioniert normal?
* mktmp genutzt.
Es wird nicht korrekt aufgeraeumt wenn das Script nicht ganz durchlaeuft / vorzeitig beendet wird...
Liegt wohl an der Variablen "madedir". Wozu hast Du sie eigentlich eingefuegt?
Ich weiss, nach dem naechsten Boot ist /tmp wieder leer. Soll auch keine Kritik sein.

Schoenes Wochenende noch.
Gruss, heinz

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 11.05.2019 18:49:00

Wenn alle Befehle unter den gleichen Bedingungen gestartet werden (bash + Befehl) ist das doch auch gewaehrleistet.
Ja. Aber die bash läuft halt schon.
Oder sehe ich das falsch? Time misst doch die Zeit, wie lange die bash gelaufen ist
Nein die Zeit in der der Befehl gelaufen ist. Da gehört weder das starten der bash noch das parsen des Befehls dazu. nicht dazu. In deinem Script startest du jedes mal eine neue bash. Dann ist wieder alles OK.
Wenn ein Befehl z.B. awk nutzt muss halt auch erst awk gestartet werden. Das gehoert m.M.n. zur Laufzeit dazu.
Ja. Aber es gibt halt einen falschen Eindruck. Die C-Varianten sind bei extrem vielen # deutlich schneller als die Konkurrenten mit yes. Eigentlich will man einen Grafen haben.
In Zeile 30
Gibt nochmal eine Unzulänglichkeit in meinem sed. Kommt nochmal ne Version.
Wozu hast Du sie eigentlich eingefuegt?
Wollte die Dateien direkt in /tmp liegen haben können. Werde den default aber wieder ändern.

benchmarke Gerade werde gleich mal Ergebnisse raus geben.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Effizient mehrere Zeichen ausgeben

Beitrag von heinz » 11.05.2019 19:22:54

wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 18:49:00
Ja. Aber die bash läuft halt schon.
Ah, ok. Jetzt verstehe ich was Du meinst. (Glaub ich zumindest...)
Besser waere es also die Befehlsdatei ausfuehrbar zu machen und zu starten, anstatt sie mit /bin/bash zu starten.
Am liebsten waere mir auch gewesen den Befehlsstring, der ja schon in einer Variable steht, direkt auszufuehren ohne ihn in eine Datei zu schreiben.
Aber da in dem String die "wildesten" Zeichen vorkommen, hab ich es nicht anders hinbekommen.
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 18:49:00
Nein die Zeit in der der Befehl gelaufen ist. Da gehört weder das starten der bash noch das parsen des Befehls dazu. nicht dazu.
Vielleicht reden wir aneinander vorbei. Ich meine, so wie es im Moment in meinem Script implementiert ist wir doch alles gemessen.
Der Start der bash, des Befehls, die Ausfuehrung des Befehle und das alles wieder zu beenden.
Anders kann ich es mir kaum vorstellen. (Kann aber auch an meiner Vorstellung liegen... ;) )
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 18:49:00
Ja. Aber es gibt halt einen falschen Eindruck.
Da hast Du natuerlich recht. Aber wie schon geschrieben, war meine Absicht irgendwie alles abzudecken um das Script auch fuer andere Zwecke nuetzlich zu machen.
(Bin auch nicht so der Profi im Programmieren...)
wanne hat geschrieben: ↑ zum Beitrag ↑
11.05.2019 18:49:00
benchmarke Gerade werde gleich mal Ergebnisse raus geben.
Klasse, bin gespannt...


Hast Du uebrigens eine Erklaerung dafuer warum bash/time korrekt funktioniert obwohl es die Optionen garnicht kennen sollte?

Gruss, heinz

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 12.05.2019 00:03:49

Vielleicht reden wir aneinander vorbei. Ich meine, so wie es im Moment in meinem Script implementiert ist wir doch alles gemessen.
Ja und ja.
In deinem Script ist das problem nicht mehr vorhanden. Nur bei den meisten Vorpostertn waren die bash-Befehle eben direkt hinter einem time und nicht eine extra bash geschrieben haben.

Hier meine Erlebnisse:
https://balja.org/pub/print.tar.xz
Hier die Ergebnisse:
https://balja.org/html/pics/printnum.svg
Leider wird das von Chrome und Firefox nicht angezeigt. Hab jetzt ne Stunde dran rumgespielt. Keine Ahnung, was da kaputt ist. Jeder andere Bildbetrachter hat kein Problem damit. Also einfach runter laden und ihr habt keine Probleme.
rot: Moderator wanne spricht, default: User wanne spricht.

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 12.05.2019 03:51:12

Hier nochmal die von mir genutzten Befehle
pastebin/?mode=view&s=40719
Noch ein paar Anmerkungen:
  • Ich habe ein paar stellen Optimiert. Viele Befehle erzeugten falsche ausgaben. Neue Befehlsliste...
  • Man achte auf die doppelt logarithmischen Achsen
  • Ich habe immer irgend wann aufgehört, wenn die Laufzeiten zu lange wurden.
  • Die Python Variante explodiert irgend wann auf Laufzeiten im Minutenbereich, weil sie irgend wann swappen anfängt.
  • Für alle Varianten, wo die Ausgabe in 8 GiB passen ist die neue schnellste Variante eine in lua:

    Code: Alles auswählen

    echo "s=\"##########\";  for i=1,9 do; s=s .. s; end;  for i=1,math.floor(%numcharsHX/5120) do; io.write(s); end; for i=1,math.fmod(%numcharsHX,5120) do; io.write(\"#\"); end " | lua
    Die ist von mir stark optimiert. Aber auch ohne Optimierungen einfach mit einem loop der n mal die 10 # ausgibt ist die schneller als alles andere. (bzw. ähnlich wie die schnelleren perl Varianten) Der speed vom lua jit ist toll.
  • Es ist schon abzusehen: Aber die C Variante die im Moment auf Platz 2 ist, geht bei noch mehr Zeichen auf Platz 1.
    Da ist mein tmpfs aber zu klein. Hab dann Zeichen nach /dev/null schreiben lassen.
    Trotzdem: Die schnellste Variante für lange Ausgaben heißt

    Code: Alles auswählen

    echo -e "#include <string.h>\n#include <unistd.h>\n#include <sys/ioctl.h>\n int main(){ int bufflen=10240; char s[bufflen]; memset(s,'#',bufflen); int i=%numcharsHX/bufflen; while(i--) write(1,s,bufflen); i=%numcharsHX%bufflen; while(i--) write(1,s,1); }" | gcc -xc -; ./a.out
    Interessant dabei: selbst bei 8000000000 macht die Compiletilme noch deutlich was aus.O3 ist deutlich länger wie ohne, Vermutlich könnte man das nochmal durch das weglassend er Header optimieren. Ich will aber korrekten C-Code schreiben. Sinnvoll ist O3 nur bei der Variante mit putchar.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Effizient mehrere Zeichen ausgeben

Beitrag von heinz » 12.05.2019 18:39:30

Wow, da ist ja eine richtig wissenschaftliche Untersuchung daraus geworden.
wanne hat geschrieben: ↑ zum Beitrag ↑
12.05.2019 00:03:49
Leider wird das von Chrome und Firefox nicht angezeigt.
Bei mir wird es korrekt angezeigt. (Firefox 66.0.5 (64-Bit))
Womit hast Du eigentlich die svg-Grafik erstellt? In der Datei "chart.eps" habe ich was von "PS-Adobe-3.0 EPSF-3.0" gelesen...

wanne
Moderator
Beiträge: 7462
Registriert: 24.05.2010 12:39:42

Re: Effizient mehrere Zeichen ausgeben

Beitrag von wanne » 12.05.2019 20:33:30

Womit hast Du eigentlich die svg-Grafik erstellt?
Inkscape. Habe auch ghostscript versucht. Produziert bei mir beides mal nur ein schwarzes Bild im Browser.
Die eps kommt einfach aus Libreoffice.
rot: Moderator wanne spricht, default: User wanne spricht.

Antworten