2017-04-17 3 views
0

Ich schrieb einen Code, der den Fluss der binären Zahlen in der Matrix simuliert. Es funktioniert einwandfrei, und wenn ich diesen Code benutze, fragen die Leute, ob ich etwas hacke. Läuft unter MacOS 10.12.3.Wie man zufälliger Algorithmus effizienter macht

#!/usr/local/bin/python3.6 
import random 
import time 

while True: 
    for j in range(204): #my full screen terminal is 204 characters wide 
     print(random.randint(0,1),end='') 
     time.sleep(0.0001) 
    print('') 

Dieser Code ist jedoch sehr ineffizient und verbraucht viel Batterie. Gibt es diesen Code ohnehin leistungsfähiger? Außerdem möchte ich keine große Menge an I/O auf meiner Festplatte haben.

+0

Generieren Sie eine volle Zeile voraus und drucken Sie dann diese vollständige Zeile. Sie wären auch überrascht, wie abhängig das von Ihrem Terminal ist. (z. B. ist das Terminal in Eclipse IDE wahrscheinlich 100 mal schneller als MS cmd). – sascha

+0

@sascha Ich denke, das ist tatsächlich das, was ich gemacht habe (ich weiß nicht, wie effizient es funktioniert), denn wenn ich etwas drucke, wird es nicht gedruckt, ohne einen neuen Zeilenbuchstaben zu finden Zeile für Zeile gedruckt. Vielleicht hat es etwas mit Pythons 'stdout' Puffer zu tun, aber ich bin mir nicht sicher. – pkqxdd

+1

Ich habe dieses Ende nicht gesehen = '' + python3, aber ich bin mir ziemlich sicher, dass der Aufbau einer großen Zeichenkette und der Aufruf des Ausdrucks einmal effizienter sein wird. – sascha

Antwort

3

Es gibt ein paar Möglichkeiten, wie Sie es verbessern könnten. Eine Möglichkeit wäre, die Anschlussbreite programmatisch zu erhalten:

import shutil 

terminal_width = shutil.get_terminal_size().columns 

Eine andere Möglichkeit, die Zufallszahl in einem Rutsch zu erzeugen wäre. Hier ist ein Vergleich von zwei verschiedenen Methoden:

In [52]: %timeit ''.join([str(random.randint(0, 1)) for i in range(terminal_width)]) 
1000 loops, best of 3: 380 µs per loop 

In [53]: N = 2**terminal_width - 1 

In [54]: %timeit bin(random.randint(0, N))[2:].zfill(terminal_width) 
100000 loops, best of 3: 3.05 µs per loop 

die Kombination der beiden, erhalten Sie:

import time 
import shutil 
import random 

terminal_width = shutil.get_terminal_size().columns 
N = 2**terminal_width - 1 

while True: 
    digits = bin(random.randint(0, N))[2:].zfill(terminal_width) 

    print(digits) 
    time.sleep(1/60) 

Beachten Sie, dass Terminal Scrollen ein limitierender Faktor in Ihrem Skript sein können, so dass Sie können zu prüfen, mit die curses Schnittstelle und zeichne alles an Ort und Stelle. Hier ist an example project des ursprünglichen Effekts mit dem Curses-Modul.

+0

Wow, vielen Dank. Ich kannte die Existenz von 'Curses' und' Shutyl' nicht. Vielleicht sollte ich mehr Zeit damit verbringen, die 1897 Seiten Dokumentation zu lesen :) – pkqxdd

+0

Um ehrlich zu sein, gab mir dieses Ding Kopfschmerzen nachdem ich 5 Minuten lang auf den Bildschirm starrte. – pkqxdd

2

Denken Sie über Ihre Bildrate nach, und, wie @sascha sagte, erzeugen Sie Ihre Zeilen vollständig.

Auch können Sie wahrscheinlich nur 500 zufällige Zeilen generieren und wiederholen, eine Reihe von Anrufen zu random speichern.

So:

  1. ein Array von 500 zufälligen Zeichenfolgen erstellen, aber viele-Zeichen breit.

  2. Schreiben Sie Ihre Schleife, um nur die gesamte Zeichenfolge zu drucken.

  3. Ändern Sie Ihre Schlafzeit zu etwas realistischer. Die meisten Videospiele zielen auf 60 fps, und sorgen Sie sich nicht um 30 fps fallen. Für so etwas könnte man wahrscheinlich mit 16-20fps durchkommen. Wie schnell ist das in Sekunden?

    Ihre vorhandene Verzögerungszeit von 0,0001 Sekunden, multipliziert mit 204 Zeichen, gibt uns 0,0204 Sekunden pro Zeile. Das sind ungefähr 50 Zeilen pro Sekunde. Verlangsamen Sie die Geschwindigkeit auf 30 Zeilen pro Sekunde und Sie werden wahrscheinlich keinen großen Unterschied bemerken, aber Sie werden viel länger schlafen.

Verwandte Themen