我使用 Rust 在 JavaScript 和 Wasm 中编写了冒泡排序算法,JS 代码比 Rust 代码快。这怎么可能?
JavaScript 代码
import * as wasm from "wasm-comparision-sort-algorithms";
function main() {
const arr = generateRandomArray({size: 50000, min: 1, max: 1000})
const arr2 = [...arr]
console.time("Bubble Sort JS")
bubbleSort(arr)
console.timeEnd("Bubble Sort JS")
wasm.handle_bubble_sort(arr2)
}
/**
* Algorithm to sort an array of numbers using the bubble sort algorithm.
* @param {Number[]} arr - The array of numbers to sort.
*/
function bubbleSort(arr) {
const len = arr.length
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - i - 1; j++) {
// Sort numbers
if (arr[j] > arr[j + 1]) {
const temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
}
/**
* Generate a random array of numbers between a range of numbers.
* @param {Number} size - The size of the array to generate.
* @param {Number} min - The minimum number in the range.
* @param {Number} max - The maximum number in the range.
* @returns {Number[]} - The generated array of numbers.
*/
function generateRandomArray({
size, min, max}) {
const arr = []
for (let i = 0; i < size; i++) {
arr.push(Math.floor(Math.random() * (max - min + 1) + min))
}
return arr
}
document.addEventListener("click", main)
锈代码
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn handle_bubble_sort(array: JsValue) {
let mut elements: Vec<u32> = array.into_serde().unwrap();
web_sys::console::time_with_label("Bubble Sort WASM");
bubble_sort(&mut elements);
web_sys::console::time_end_with_label("Bubble Sort WASM");
alert(&format!("The sum of all elements is {}", sum));
}
/*
* Create a bubble sort algorithm
*/
pub fn bubble_sort(array: &mut [u32]) {
let _i = 0;
let _j = 1;
let _size_array = array.len();
for _i in 0.._size_array {
for _j in 0.._size_array - _i - 1 {
unsafe {
let t1 = *array.get_unchecked(_j);
let t2 = *array.get_unchecked(_j + 1);
if t1 > t2 {
array.swap_unchecked(_j, _j+1);
}
}
}
}
}
货运.toml
[package]
name = "wasm-comparision-sort-algorithms"
version = "0.1.0"
authors = ["a simple mortal"]
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = { version = "0.2.63", features = ["serde-serialize"] }
serde = { version = "1.0", features = ["derive"] }
web-sys = { version = "0.3.55", features = ["console"] }
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
#
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.5", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.3.13"
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level=3 # Optimal for time execution
平均次数:
- JavaScript:5115 毫秒
- 生锈:9499 毫秒
环境版本:
- 我正在使用 wasm-pack 版本0.10.1
- 从 localhost 服务器使用的节点版本是:16.13.0
- Cargo 和 Rustc 版本:1.57.0
- 我正在测试 Brave 浏览器版本:1.31.88
我wasm-pack build --release
用来构建项目。