Angenommen, die Variable x
enthält eine Zahl wie Integer oder Float.
Die Berechnung des Quadrats von "x" ist
x ** 2
Aber wenn Sie so schnell wie möglich rechnen wollen
x * x
Du solltest schreiben. Letzteres ist bei weitem das schnellste. Ersteres ist langsam.
Zuerst
gem install benchmark_driver
Installieren Sie dann Benchmark_driver und installieren Sie es.
square.yaml
prelude: |
x = 3.0
benchmark:
- "x ** 2"
- "x * x"
Bereiten Sie eine YAML-Datei mit dem Namen vor
benchmark-driver square.yaml
Sie können es mit vergleichen.
Gemessen mit "Ruby 2.7.1p83 (2020-03-31 Revision a0c7c23c9c) [x86_64-darwin17]" sind die Ergebnisse wie folgt.
x * x: 92940175.9 i/s
x ** 2: 15605744.0 i/s - 5.96x slower
Beeindruckend!
Nun, selbst wenn es langsam ist, kann es 15 Millionen Mal pro Sekunde ausgeführt werden, daher ist diese Langsamkeit nur dann ein Problem, wenn viele numerische Berechnungen durchgeführt werden [^ sp].
[^ sp]: Wenn Sie ein Programm beschleunigen möchten, ist es wichtig, die Zahlen durch einen Benchmark-Test richtig zu verfolgen, und es ist sinnlos, die Blutlinie zu erhöhen, um den Teil zu optimieren, der die Ausführungszeit des gesamten Programms nicht beeinflusst. Ich möchte daran denken.
Es wurden Änderungen vorgenommen, um "** 2" speziell für Float zu behandeln und schneller zu berechnen. Sie können dies mit Ruby 3.0.0-Preview1 überprüfen.
Wenn Sie Ruby in rbenv haben, können Sie es einfach mit Benchmark_Driver testen. Diesmal für dieselbe YAML-Datei wie zuvor
benchmark-driver square.yaml --rbenv "2.7.2;3.0.0-preview1"
Und. Die Ergebnisse sind wie folgt.
x ** 2
3.0.0-preview1: 37039739.4 i/s
2.7.2: 16010580.7 i/s - 2.31x slower
x * x
2.7.2: 91881050.6 i/s
3.0.0-preview1: 88138626.5 i/s - 1.04x slower
"x * x", eher "3.0.0-Vorschau1" ist langsamer, aber dies liegt im Fehlerbereich.
x ** 2
ist 2,3 mal schneller.
Nun, "x * x" ist immer noch mehr als doppelt so schnell wie "x ** 2", aber ich denke, es ist immer noch eine wichtige Entwicklung. Es gibt viele Codes wie "x ** 2" und sie machen es schneller, ohne etwas zu tun.
In einigen Fällen möchten Sie möglicherweise "** 2" auf Kosten der Geschwindigkeit verwenden. In diesem Fall befindet sich der Ausdruck, den Sie quadrieren möchten, nicht in der Variablen. Nun, diese Art von Bild:
items.map.with_index{ |item, i| (a * item.value + b[i]) ** 2 }
Dies
items.map.with_index{ |item, i| (a * item.value + b[i]) * (a * item.value + b[i]) }
Es ist nicht nur redundant, sondern verlangsamt es wahrscheinlich auch. Sobald Sie den Wert des Ausdrucks in eine Variable eingefügt haben
items.map.with_index{ |item, i| x = a * item.value + b[i]; x * x }
Wird geschrieben werden. Wenn Geschwindigkeit die höchste Priorität hat, würde ich es so schreiben, aber wenn Sie sagen "Ich möchte Geschwindigkeit, aber ich möchte auch Einfachheit", könnte ich "** 2" verwenden.