Die Aufgabe besteht darin, einen Weg zu finden, um eine horizontale Linie in einem Array von 16-Bit-Ganzzahlen zu zeichnen.
Wir gehen von einem 256x192-Pixel-Array mit 16 Pixeln pro Wort aus. Eine Zeile ist ein zusammenhängender Lauf von gesetzten (1) Bits. Zeilen können in der Mitte eines Wortes beginnen, andere Wörter überlappen und in einem beliebigen Wort enden. Sie können auch mit demselben Wort beginnen und enden. Sie werden möglicherweise nicht in die nächste Zeile übernommen. Hinweis: Die mittleren Wörter sind einfach - schreiben Sie einfach 0xffff, aber die Kanten werden schwierig, ebenso wie die Behandlung des Falls für Anfang und Ende im selben Wort. Eine Funktion / Prozedur / Routine muss eine x0- und x1-Koordinate annehmen, die die horizontalen Start- und Stopppunkte sowie jede Koordinate angibt.
Ich schließe mich davon aus, weil ich selbst einen nahezu identischen Algorithmus für einen eingebetteten Prozessor entworfen habe, aber ich bin gespannt, wie andere vorgehen würden. Bonuspunkte für die Verwendung relativ schneller Operationen (zum Beispiel wäre eine 64-Bit-Multiplikations- oder Gleitkommaoperation auf einem eingebetteten Computer nicht schnell, eine einfache Bitverschiebung jedoch).
quelle
Antworten:
Dieser Code setzt voraus, dass sowohl x0 als auch x1 inklusive Endpunkte sind und dass Wörter Little Endian sind (dh das (0,0) Pixel kann mit gesetzt werden
array[0][0]|=1
).quelle
Python
Der Haupttrick besteht darin, eine Nachschlagetabelle zum Speichern von Bitmasken der Pixel zu verwenden. Dies spart einige Operationen. Eine 1-KB-Tabelle ist heutzutage selbst für eine eingebettete Plattform nicht so groß
Wenn der Platz sehr knapp ist, kann die Nachschlagetabelle für den Preis von ein paar & 0xf auf nur 64B reduziert werden
Dieser Code ist in Python, kann aber einfach in jede Sprache portiert werden, die Bitoperationen unterstützt.
Wenn Sie C verwenden, können Sie die Schleife mit dem Gerät
switch
von Duff abwickeln . Da die Zeile maximal 16 Wörter breit ist, würde ich dieswitch
auf 14 Zeilen erweitern und auf diewhile
insgesamt verzichten .quelle
Hier ist eine C-Version meiner Python-Antwort, die die switch-Anweisung anstelle der while-Schleife verwendet und die Indizierung durch Inkrementieren eines Zeigers anstelle des Array-Index reduziert
Die Größe der Nachschlagetabelle kann erheblich reduziert werden, indem T [x1 & 0xf] und U [x2 & 0xf] für einige zusätzliche Anweisungen verwendet werden
quelle
Scala,
7s / 1M Zeilen4,1s / 1M Zeilenerste Implementierung:
Nachdem ich den inneren Methodenaufruf eliminiert und die for- durch eine while-Schleife ersetzt habe, wird auf meinem 2-GHz-Single-Core mit Scala 2.8 1 Mio. freigesetzt. Linien in 4,1s sek. anstelle der ersten 7s.
Testcode und Aufruf:
Leistungstest:
Getestet mit der Unix-Tool-Zeit, Vergleich der Benutzerzeit, einschließlich Startzeit, kompiliertem Code, keine JVM-Startphase.
Das Erhöhen der Anzahl der Zeilen zeigt, dass für jede neue Million zusätzliche 3,3 Sekunden benötigt werden.
quelle