Es wird gesagt, dass die JS-Funktion WebAssembly die Berechnung beschleunigt, aber ich habe auch die Theorie gesehen, dass dies nicht der Fall ist, daher werde ich sie kurz überprüfen. Hier werde ich mich auf die Geschwindigkeit der reinen numerischen Berechnung konzentrieren, wie z. B. Dateigröße usw. Aspekte sind von der Prüfung ausgeschlossen. Der Titel lautet "[Numerische Berechnung]", es ist jedoch derzeit nicht geplant, eine Fortsetzung zu schreiben.
Frühere Forschungen:
Nach dem Artikel "Vergleich der Berechnungsgeschwindigkeiten in verschiedenen Sprachen" werde ich die Bewertung der Leibniz-Reihe aufnehmen. Ich weiß nicht, ob es so oft berechnet wird ... Außerdem wird WebAssembly mit der Geschwindigkeit des nativen Codes in Bezug auf die Geschwindigkeit verglichen, die der nativen Ausführung nahe kommt.
[04-22 19: 40] Ein Codefehler wurde behoben und gleichzeitig die Anzahl der Schleifen auf 1e9 erhöht.
Die Umgebung ist Debian 10.3 unter Win10 (WSL), Intel Core i7-6700 CPU bei 3,40 GHz.
Unter dem Gesichtspunkt des numerischen Berechnungsbenchmarks denke ich, dass die Geschwindigkeit der Muttersprache C immer noch der Standard ist, daher werde ich mit der Sprache C beginnen. Sie wird anhand des Codes des Originalartikels korrigiert.
leibniz.c
# include <stdio.h>
int main(void){
int i;
double sum = 0.0;
int signum = 1;
double denom = 1.0;
for (i = 0; i<=1e9; i++) {
sum += signum / denom;
signum *= -1;
denom += 2.0;
};
printf("Ans:%.16f\n", 4.0*sum);
return 0;
}
Rust
leibniz.rs
fn main() {
let mut sum: f64 = 0.0;
let mut signum = 1;
let mut denom = 1.0;
for _ in 0..=1_000_000_000 {
sum += signum as f64 / denom;
signum *= -1;
denom += 2.0;
}
println!("Ans:{:.16}", 4.*sum);
}
JS (Node.js)
leibniz.js
var sum = 0.0;
var signum = 1;
var denom = 1.0;
for (var i = 0; i<=1e9; i++) {
sum += signum / denom;
signum *= -1;
denom += 2.0;
}
console.log('%d',4.0*sum);
Dieser Wert ist das Ergebnis einer nur einmaligen Ausführung, wurde jedoch mehrmals wiederholt und es wurde bestätigt, dass der Fehler nur die letzte schwankende Ziffer war.
$ gcc --version
gcc (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc leibniz.c -o leibniz
$ time ./leibniz
real 0m2.596s
user 0m2.578s
sys 0m0.000s
$ gcc -O3 leibniz.c -o leibniz
$ time ./leibniz
Ans:3.1415926545880506
real 0m1.136s
user 0m1.125s
sys 0m0.016s
$ gcc -O3 -march=native leibniz.c -o leibniz
$ time ./leibniz
Ans:3.1415926545880506
real 0m1.133s
user 0m1.125s
sys 0m0.000s
$ rustc --version
rustc 1.42.0 (b8cedc004 2020-03-09)
$ rustc leibniz.rs
$ time ./leibniz
Ans:3.1415926545880506
real 0m36.107s
user 0m36.094s
sys 0m0.016s
$ rustc -C opt-level=3 leibniz.rs
$ time ./leibniz
Ans:3.1415926545880506
real 0m1.124s
user 0m1.094s
sys 0m0.031s
$ rustc -C opt-level=3 -C target-cpu=native leibniz.rs
$ time ./leibniz
Ans:3.1415926545880506
real 0m1.181s
user 0m1.156s
sys 0m0.031s
$ node --version
v12.16.2
$ time node leibniz.js
3.1415926545880506
real 0m1.989s
user 0m1.953s
sys 0m0.047s
~~ Selbst bei der Optimierung ist C unerwartet langsam ... Rost ist ungefähr viermal schneller, aber ich frage mich, ob ich einen Fehler gemacht habe. Rost ohne Optimierung war am langsamsten und Rost mit Optimierung war am schnellsten. . ~~
Nach der Optimierung waren sowohl die C-Sprache als auch Rust etwa 1,13 Sekunden lang. Der Knoten ist etwa 75% langsamer.
Ich habe derzeit kein Google Chrome, daher habe ich es nur mit Mozilla Firefox 75.0 unter Win10 versucht.
JS
Ich bin nicht an der Zeit des HTML-Renderings usw. interessiert. Klicken Sie also auf die Schaltfläche, um die Berechnung zu starten.
leibniz.html
<!DOCTYPE html>
<html>
<head>
<title>Leibniz Series</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<button id="start">Start!</button>
<script>
function leibniz() {
var sum = 0.0;
var signum = 1;
var denom = 1.0;
for (var i = 0; i<=1e9; i++) {
sum += signum / denom;
signum *= -1;
denom += 2.0;
}
console.log('%f',4.0*sum);
}
let button = document.getElementById("start");
button.addEventListener("click", () => {
const startTime = performance.now()
leibniz();
const endTime = performance.now();
console.log(endTime - startTime);
});
</script>
</body>
</html>
Das Ergebnis war ~~ 0.168 Sek. ~~ 1.660 Sek. Es ist nur ungefähr ~~ 30% ~~ 45% langsamer als die optimierte C-Sprache. Es ist beängstigend schnell ...
Rust (wasm)
src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace=console)]
fn log(s: String);
}
#[wasm_bindgen]
pub fn leibniz() {
let mut sum: f64 = 0.0;
let mut signum = 1;
let mut denom = 1.0;
for _ in 0..=1_000_000_000 {
sum += signum as f64 / denom;
signum *= -1;
denom += 2.0;
}
log(format!("Ans:{:.16}", 4.*sum));
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>Leibniz Series</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<button id="start">Start!</button>
<script type="module">
import init, {leibniz} from '/pkg/rust_wasm.js';
let button = document.getElementById("start");
button.addEventListener("click", async () => {
const startTime = performance.now()
await init();
leibniz();
const endTime = performance.now();
console.log(endTime - startTime);
});
</script>
</body>
</html>
Das Ergebnis war ~ ~ 0,035 Sek. ~ ~ 1,462 Sek. ~~ Es ist fast die gleiche Geschwindigkeit wie Rust nach der Optimierung (ungefähr 10% langsamer) ~~ Schneller als JS und ungefähr 30% langsamer als native.
Die Zeit zum Aufrufen der Initialisierungsfunktion "init ()" wird ebenfalls gemessen, aber selbst native Benutzer messen die Zeit vom Lesen der Binärdatei bis zum Ende der Verarbeitung, sodass die Messung so gleich wie möglich ist. Übrigens, als ich die Zeit nach dem Aufruf von "init" gemessen habe, waren es ungefähr ~ ~ 0,015 Sekunden ~ ~ 1,381 Sekunden.
Es wurde bestätigt, dass WebAssembly in der reinen numerischen Berechnung selbst ungefähr 5-mal schneller als JS ist, und es ist ungefähr 15% schneller als native, aber nicht so schnell wie native. In diesem Artikel jedoch Da der Code nur vier Regeln für Ganzzahl- und Gleitkommazahlen enthält, kann sich das Ergebnis bei anderer Verarbeitung (z. B. Leistungsstärke), Funktionsaufruf und Speicherzugriff erneut ändern. In früheren Studien scheint es, dass wasm JS bisher nicht überzeugt hat. ~~
Was passiert übrigens, wenn Sie wasm in Node.js aufrufen? Ich dachte, ich würde es versuchen, aber ich bin erschöpft, also werde ich es wieder tun.
Recommended Posts