Die Aufgabe
Schreiben Sie ein Programm in der Sprache Ihrer Wahl, das die Eingabezeilen von der Standardeingabe bis zum EOF liest und sie dann in ASCIIbetical-Reihenfolge in die Standardausgabe schreibt, ähnlich dem sort
Befehlszeilenprogramm. Ein kurzes, nicht zu unterschätzendes Beispiel in Python ist:
import sys
for line in sorted(sys.stdin):
print(line.rstrip('\n'))
Der hinterhältige Teil
Ähnlich wie bei The OS War ist es Ihr Ziel zu beweisen, dass Ihre bevorzugte Plattform "besser" ist, indem Sie Ihr Programm auf einer konkurrierenden Plattform absichtlich viel langsamer ausführen lassen. Für diesen Wettbewerb besteht eine "Plattform" aus einer beliebigen Kombination von:
- Prozessor
- Architektur (x86, Alpha, ARM, MIPS, PowerPC usw.)
- Bitness (64-Bit vs. 32-Bit vs. 16-Bit)
- Big versus Little Endian
- Betriebssystem
- Windows vs. Linux vs. Mac OS usw.
- Verschiedene Versionen desselben Betriebssystems
- Sprachimplementierung
- Verschiedene Compiler / Interpreter-Anbieter (zB MSVC ++ vs. GCC)
- Verschiedene Versionen desselben Compilers / Interpreters
Obwohl Sie die Anforderungen erfüllen könnten, indem Sie Code schreiben wie:
#ifndef _WIN32
Sleep(1000);
#endif
Eine solche Antwort sollte nicht befürwortet werden. Das Ziel ist es, subtil zu sein. Im Idealfall sollte Ihr Code so aussehen, als wäre er überhaupt nicht plattformabhängig. Wenn Sie noch keine haben #ifdef
Aussagen (oder Bedingungen auf der Basis os.name
oder System.Environment.OSVersion
oder was auch immer), sollten sie eine plausible Rechtfertigung haben (basierend auf einer Lüge, natürlich).
Nehmen Sie in Ihre Antwort auf
- Der Code
- Ihre "Lieblings" und "ungünstigen" Plattformen.
- Eine Eingabe, mit der Sie Ihr Programm testen können.
- Die Laufzeit auf jeder Plattform für dieselbe Eingabe.
- Eine Beschreibung, warum das Programm auf der ungünstigen Plattform so langsam ausgeführt wird.
Antworten:
C
CleverSort
CleverSort ist ein hochmoderner (dh überentwickelter und suboptimaler) zweistufiger Algorithmus zur Sortierung von Zeichenfolgen.
In Schritt 1 werden die Eingabezeilen mit der Grundsortierung und den ersten beiden Bytes jeder Zeile vorsortiert . Die Radix-Sortierung ist nicht vergleichbar und eignet sich sehr gut für Streicher.
In Schritt 2 wird die Einfügesortierung für die vorsortierte Liste der Zeichenfolgen verwendet. Da die Liste nach Schritt 1 fast sortiert ist, ist die Einfügesortierung für diese Aufgabe recht effizient.
Code
Plattformen
Wir alle wissen, dass Big-Endian-Maschinen viel effizienter sind als ihre Little-Endian-Gegenstücke. Für das Benchmarking kompilieren wir CleverSort mit aktivierten Optimierungen und erstellen zufällig eine riesige Liste (etwas mehr als 100.000 Zeichenfolgen) von 4-Byte-Zeilen:
Big-Endian-Benchmark
Nicht zu schäbig.
Little-Endian Bechmark
Boo, kleiner Endian! Boo!
Beschreibung
Das Sortieren von Einfügungen ist für fast sortierte Listen sehr effizient, für zufällig sortierte Listen jedoch schrecklich ineffizient.
CleverSorts hinterhältiger Teil ist das FIRSTSHORT- Makro:
Auf Big-Endian-Computern führt das lexikografische Ordnen einer Zeichenfolge aus zwei 8-Bit-Ganzzahlen oder das Konvertieren in 16-Bit-Ganzzahlen und das anschließende Ordnen derselben zu denselben Ergebnissen.
Natürlich ist dies auch auf Little-Endian-Maschinen möglich, aber das Makro sollte es gewesen sein
was auf allen Plattformen wie erwartet funktioniert.
Der obige "Big-Endian-Benchmark" ist eigentlich das Ergebnis der Verwendung des richtigen Makros.
Mit dem falschen Makro und einer Little-Endian-Maschine wird die Liste nach dem zweiten Zeichen jeder Zeile vorsortiert , was aus lexikografischer Sicht zu einer zufälligen Reihenfolge führt. Die Einfügesortierung verhält sich in diesem Fall sehr schlecht.
quelle
Python 2 gegen Python 3
Offensichtlich ist Python 3 einige Größenordnungen schneller als Python 2. Nehmen wir als Beispiel die folgende Implementierung des Shellsort- Algorithmus:
Code
Benchmark
Bereiten Sie einen Testeingang vor. Dies ist Dennis Antwort entnommen, aber mit weniger Worten - Python 2 ist sooo langsam ...
Python 2
Python 3
Wo ist der hinterhältige Code?
Ich nehme an, dass einige Leser den Trickster selbst jagen möchten, also verstecke ich die Antwort mit einem Spoiler-Tag.
Bonus 1:
Bonus 2:
quelle
flag
Sieht schreibgeschützt aus. Können Sie sie nicht entfernen? Auchr
scheint überflüssig , wenn Sie das tunif lst[i+h] < lst[i]: ...
. Auf der anderen Seite, wenn Sie behalten,r
warum der Swap? Könntest du nicht einfach tunlst[i+h] = lst[i]
? Ist das alles eine absichtliche Ablenkung?