Denken Sie, dass diese beiden Optionen zum Überprüfen der Bedingungen innerhalb einer Schleife eine gleichwertige Leistung aufweisen?
if a > b && c*2 > d { .... }
Alles begann mit einem „Aufwärmen für das Gehirn“. Es war notwendig, ein Beispiel für eine optimale Suche nach einem Array von ganzen Zahlen [-x .... x] der größten geraden Zahl zu geben. Ich habe mich gefragt, wie viel höher die Leistung wäre, wenn ich, um eine gerade Zahl herauszufinden oder nicht, die logische Multiplikation mit 1 verwenden würde.
Meine Programmiererfahrung auf Go ist nicht sehr groß, etwas mehr als anderthalb Jahre. Ich habe sie zwar oft verwendet, aber nur für zweckmäßige Zwecke (naja, vielleicht mit Ausnahme eines Projekts, das sich auf einen hoch geladenen http-Dienst bezieht), also habe ich damit begonnen. Öffnen Sie GoLand und schreiben Sie einen einfachen Test
package main import ( "fmt" "log" "math" "math/rand" "time" ) const size = 100000000
Wir erhalten ein Ergebnis, das zeigt, dass je höher der Schwellenwert, desto häufiger Leistungsschwankungen auftreten.
Vergleichenmax threshold: 128
maxEvenDividing result: 126 duration 116.0067ms
maxEvenConjunction result: 126 duration 116.0066ms
max threshold: 16384
maxEvenDividing result: 16382 duration 115.0066ms
maxEvenConjunction result: 16382 duration 111.0064ms
......
max threshold: 8388608
maxEvenDividing result: 8388606 duration 109.0063ms
maxEvenConjunction result: 8388606 duration 109.0062ms
max threshold: 16777216
maxEvenDividing result: 16777214 duration 108.0062ms
maxEvenConjunction result: 16777214 duration 109.0062ms
max threshold: 33554432
maxEvenDividing result: 33554430 duration 114.0066ms
maxEvenConjunction result: 33554430 duration 110.0063ms
max threshold: 67108864
maxEvenDividing result: 67108860 duration 111.0064ms
maxEvenConjunction result: 67108860 duration 109.0062ms
max threshold: 134217728
maxEvenDividing result: 134217726 duration 108.0062ms
maxEvenConjunction result: 134217726 duration 109.0063ms
max threshold: 268435456
maxEvenDividing result: 268435446 duration 111.0063ms
maxEvenConjunction result: 268435446 duration 110.0063ms
Es ist klar, dass in diesem Fall für unterschiedliche Schwellenwerte, für die wir unterschiedliche Testdatensätze haben, die Prozessorlast (auf meinem i5-2540M-Laptop) um 20,30% variiert und der von der Anwendung unter GoLand belegte Speicher durchschnittlich 813 MB beträgt - dies ist auch so Um die Zuverlässigkeit des Ergebnisses zu beeinträchtigen, müssen Sie die Aufbewahrung von Testsätzen auf der Festplatte implementieren und alle Tests für jeden Schwellenwert isoliert voneinander ausführen.
Und wenn ich darüber nachdenke, wie ich all dies mit minimalen Kosten implementieren kann, korrigiere ich automatisch die Zustandsprüfung
if value > current && value&1 == 0 { current = value }
auf
if value <= current { continue; } if value&1 == 0 { current = value }
Ich führe die Tests erneut durch ... und höre auf, etwas zu verstehen :)
Die für die Ausführung aufgewendete Zeit beginnt sich nicht mehr um Prozent / Bruchteil eines Prozent zu unterscheiden, sondern um 10,15%. Ich füge schnell zwei weitere Tests hinzu:
func maxEvenDividing2(name string, arr []int32) Result { start := time.Now() var current int32 = math.MinInt32 for _, value := range arr { if value <= current { continue } if value%2 == 0 { current = value } } duration := time.Since(start) result := Result{name, duration, current} return result } func maxEvenConjunction2(name string, arr []int32) Result { start := time.Now() var current int32 = math.MinInt32 for _, value := range arr { if value <= current { continue } if value&1 == 0 { current = value } } duration := time.Since(start) result := Result{name, duration, current} return result }
Ich starte und bekomme dieses Bild:anfängliche Array-Kapazität: 100000000
Maximaler Schwellenwert: 128
maxEvenDividing Ergebnis: 126 Dauer 116.0066ms
maxEvenDividing2 Ergebnis: 126 Dauer 79.0045ms
maxEvenConjunction Ergebnis: 126 Dauer 114.0065ms
maxEvenConjunction2 Ergebnis: 126 Dauer 83.0048ms
Maximaler Schwellenwert: 256
maxEvenDividing Ergebnis: 254 Dauer 111.0063ms
maxEvenDividing2 Ergebnis: 254 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 254 Dauer 110.0063ms
maxEvenConjunction2 Ergebnis: 254 Dauer 80.0046ms
Maximaler Schwellenwert: 512
maxEvenDividing Ergebnis: 510 Dauer 114.0066ms
maxEvenDividing2 Ergebnis: 510 Dauer 80.0045ms
maxEvenConjunction Ergebnis: 510 Dauer 110.0063ms
maxEvenConjunction2 Ergebnis: 510 Dauer 80.0046ms
Maximaler Schwellenwert: 1024
maxEvenDividing Ergebnis: 1022 Dauer 109.0063ms
maxEvenDividing2 Ergebnis: 1022 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 1022 Dauer 111.0063ms
maxEvenConjunction2 Ergebnis: 1022 Dauer 81.0047ms
Maximaler Schwellenwert: 2048
maxEvenDividing Ergebnis: 2046 Dauer 114.0065ms
maxEvenDividing2 Ergebnis: 2046 Dauer 79.0045ms
maxEvenConjunction Ergebnis: 2046 Dauer 113.0065ms
maxEvenConjunction2 Ergebnis: 2046 Dauer 81.0046ms
Maximaler Schwellenwert: 4096
maxEvenDividing Ergebnis: 4094 Dauer 114.0065ms
maxEvenDividing2 Ergebnis: 4094 Dauer 80.0046ms
maxEvenConjunction Ergebnis: 4094 Dauer 111.0063ms
maxEvenConjunction2 Ergebnis: 4094 Dauer 78.0045ms
Maximaler Schwellenwert: 8192
maxEvenDividing Ergebnis: 8190 Dauer 107.0062ms
maxEvenDividing2 Ergebnis: 8190 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 8190 Dauer 111.0063ms
maxEvenConjunction2 Ergebnis: 8190 Dauer 77.0044ms
Maximaler Schwellenwert: 16384
maxEvenDividing Ergebnis: 16382 Dauer 109.0063ms
maxEvenDividing2 Ergebnis: 16382 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 16382 Dauer 108.0062ms
maxEvenConjunction2 Ergebnis: 16382 Dauer 77.0044ms
Maximaler Schwellenwert: 32768
maxEvenDividing Ergebnis: 32766 Dauer 112.0064ms
maxEvenDividing2 Ergebnis: 32766 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 32766 Dauer 109.0062ms
maxEvenConjunction2 Ergebnis: 32766 Dauer 78.0045ms
Maximaler Schwellenwert: 65536
maxEvenDividing Ergebnis: 65534 Dauer 109.0062ms
maxEvenDividing2 Ergebnis: 65534 Dauer 75.0043ms
maxEvenConjunction Ergebnis: 65534 Dauer 109.0063ms
maxEvenConjunction2 Ergebnis: 65534 Dauer 79.0045ms
Maximaler Schwellenwert: 131072
maxEvenDividing Ergebnis: 131070 Dauer 108.0061ms
maxEvenDividing2 Ergebnis: 131070 Dauer 76.0044ms
maxEvenConjunction Ergebnis: 131070 Dauer 110.0063ms
maxEvenConjunction2 Ergebnis: 131070 Dauer 80.0046ms
Maximaler Schwellenwert: 262144
maxEvenDividing Ergebnis: 262142 Dauer 110.0063ms
maxEvenDividing2 Ergebnis: 262142 Dauer 76.0044ms
maxEvenConjunction Ergebnis: 262142 Dauer 107.0061ms
maxEvenConjunction2 Ergebnis: 262142 Dauer 78.0044ms
Maximaler Schwellenwert: 524288
maxEvenDividing Ergebnis: 524286 Dauer 109.0062ms
maxEvenDividing2 Ergebnis: 524286 Dauer 78.0045ms
maxEvenConjunction Ergebnis: 524286 Dauer 109.0062ms
maxEvenConjunction2 Ergebnis: 524286 Dauer 80.0046ms
Maximaler Schwellenwert: 1048576
maxEvenDividing Ergebnis: 1048574 Dauer 109.0063ms
maxEvenDividing2 Ergebnis: 1048574 Dauer 80.0045ms
maxEvenConjunction Ergebnis: 1048574 Dauer 114.0066ms
maxEvenConjunction2 Ergebnis: 1048574 Dauer 78.0044ms
Maximaler Schwellenwert: 2097152
maxEvenDividing Ergebnis: 2097150 Dauer 111.0064ms
maxEvenDividing2 Ergebnis: 2097150 Dauer 79.0045ms
maxEvenConjunction Ergebnis: 2097150 Dauer 112.0064ms
maxEvenConjunction2 Ergebnis: 2097150 Dauer 77.0044ms
Maximaler Schwellenwert: 4194304
maxEvenDividing Ergebnis: 4194302 Dauer 111.0063ms
maxEvenDividing2 Ergebnis: 4194302 Dauer 78.0045ms
maxEvenConjunction Ergebnis: 4194302 Dauer 111.0063ms
maxEvenConjunction2 Ergebnis: 4194302 Dauer 77.0044ms
Maximaler Schwellenwert: 8388608
maxEvenDividing Ergebnis: 8388606 Dauer 109.0062ms
maxEvenDividing2 Ergebnis: 8388606 Dauer 78.0045ms
maxEvenConjunction Ergebnis: 8388606 Dauer 114.0065ms
maxEvenConjunction2 Ergebnis: 8388606 Dauer 78.0045ms
Maximaler Schwellenwert: 16777216
maxEvenDividing Ergebnis: 16777214 Dauer 109.0062ms
maxEvenDividing2 Ergebnis: 16777214 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 16777214 Dauer 109.0063ms
maxEvenConjunction2 Ergebnis: 16777214 Dauer 77.0044ms
Maximaler Schwellenwert: 33554432
maxEvenDividing Ergebnis: 33554430 Dauer 113.0065ms
maxEvenDividing2 Ergebnis: 33554430 Dauer 78.0045ms
maxEvenConjunction Ergebnis: 33554430 Dauer 110.0063ms
maxEvenConjunction2 Ergebnis: 33554430 Dauer 80.0045ms
Maximaler Schwellenwert: 67108864
maxEvenDividing Ergebnis: 67108860 Dauer 112.0064ms
maxEvenDividing2 Ergebnis: 67108860 Dauer 77.0044ms
maxEvenConjunction Ergebnis: 67108860 Dauer 112.0064ms
maxEvenConjunction2 Ergebnis: 67108860 Dauer 80.0046ms
Maximaler Schwellenwert: 134217728
maxEvenDividing Ergebnis: 134217726 Dauer 109.0063ms
maxEvenDividing2 Ergebnis: 134217726 Dauer 78.0044ms
maxEvenConjunction Ergebnis: 134217726 Dauer 114.0065ms
maxEvenConjunction2 Ergebnis: 134217726 Dauer 81.0047ms
Maximaler Schwellenwert: 268435456
maxEvenDividing Ergebnis: 268435446 Dauer 111.0064ms
maxEvenDividing2 Ergebnis: 268435446 Dauer 79.0045ms
maxEvenConjunction Ergebnis: 268435446 Dauer 114.0065ms
maxEvenConjunction2 Ergebnis: 268435446 Dauer 79.0045ms
Maximaler Schwellenwert: 536870912
maxEvenDividing Ergebnis: 536870910 Dauer 107.0062ms
maxEvenDividing2 Ergebnis: 536870910 Dauer 76.0043ms
maxEvenConjunction Ergebnis: 536870910 Dauer 109.0062ms
maxEvenConjunction2 Ergebnis: 536870910 Dauer 80.0046ms
Eine klare Erklärung, warum der Go-Compiler den Code nicht optimiert und immer die zweite Bedingung überprüft, auch wenn die erste falsch ist, habe ich nicht gefunden. Oder ist mein Auge nur "verschwommen" und ich sehe keinen offensichtlichen Fehler? Oder müssen Sie dem Compiler einige spezielle Anweisungen geben? Ich würde mich über vernünftige Kommentare freuen.
PS: Ja, zum Spaß habe ich ähnliche Tests auf Java 5 und Java 7/8 durchgeführt - alles ist klar, die Ausführungszeit ist gleich.