Node.js против Rust, но Node.js быстрее [закрыто] ⇐ Javascript
Node.js против Rust, но Node.js быстрее [закрыто]
У меня есть функция с именем
сетка
который взят из задачи динамического программирования «grid Traveler». Я дважды написал одну и ту же функцию на JavaScript и Rust и протестировал 10 миллионов вычислений, запоминая обе функции.
JavaScript:
const Grid = (m, n, memo) => { константный ключ = m + ',' + n; if (ключ в заметке) вернуть memo[ключ] const max = Math.max(m, n) const min = Math.min(m, n) const d = Array.from({ length: max }, () => 1) for (пусть я = 1; я < min; я++) { for (let j = i; j < max; j++) { константный индекс = j если (я === j) { д[индекс] *= 2 } еще { d[индекс] = d[индекс] + d[индекс - 1] } } } памятка[ключ] = d[макс. - 1] вернуть d[макс - 1] } пусть старт = новая дата().getTime() константная заметка = {} для (пусть я = 0; я < 10_000_000; я++) { // сетка(18, 18) сетка(18, 18, памятка) } console.log(новая дата().getTime() - начало) Ржавчина:
use std::collections::hash_map::Entry; используйте std::collections::HashMap; используйте std::time::SystemTime; fngrid(m: &usize, n: &usize, memo: &mut HashMap) -> u64 { let key = m.to_string() + "," + &n.to_string(); сопоставить memo.entry(ключ) { Entry::Occupied(x) => *x.get(), Запись::Вакант(v) => { пусть макс: &usize; пусть мин: &usesize; если м > п { макс = &м; мин = & п; } еще { Макс = &n; мин = &м; } пусть mut d = Vec::::with_capacity(*max); для _ в 0..*max { д.push(1); } для меня через 1..*мин { для j в i..*max { если я == j { д[j] *= 2; } еще { d[j] = d[j] + d[j - 1]; } } } v.insert(d[*max - 1]); вернуть d[*max - 1]; } } } fn main() { пусть start = SystemTime::now(); let mut memo = HashMap::::new(); пусть т = 18; пусть n = 18; для _ через 0..10_000_000 { сетка(&m, &n, &mut memo); // сетка(&m, &n); } println!("{}", start.elapsed().unwrap().as_millis()); } Результаты тестирования с помощью команд:
узел index.js = 9
грузовой пробег --release = 1614
Я подумал, что, возможно, использование хэш-карты — не такая уж хорошая идея, поэтому попробовал макрос #[memoize] из этого ящика.
Результаты оказались разочаровывающими:
узел index.js = 9
грузовой пробег --release = 254
Почему это происходит и как лучше всего запомнить эту функцию в Rust?
Также результаты тестов без запоминания:
узел index.js = 15424
грузовой пробег --release = 2400
(Изменения от Хаима Фридмана) + (переход на 100 миллионов звонков):
Ржавчина:
use std::collections::hash_map::Entry; используйте std::time::Instant; используйте Rustc_hash::FxHashMap; fngrid(m: usesize, n: usesize, memo: &mut FxHashMap) -> u64 { пусть ключ: (использовать, использовать) = (м, п); сопоставить memo.entry(ключ) { Entry::Occupied(x) => *x.get(), Запись::Вакант(v) => { пусть макс: &usize; пусть мин: &usesize; если м > п { макс = &м; мин = & п; } еще { Макс = &n; мин = &м; } пусть mut d = Vec::::with_capacity(*max); для _ в 0..*max { д.push(1); } для меня через 1..*мин { для j в i..*max { если я == j { д[j] *= 2; } еще { d[j] = d[j] + d[j - 1]; } } } v.insert(d[*max - 1]); вернуть d[*max - 1]; } } } fn main() { пусть start = Instant::now(); let mut memo = FxHashMap::::default(); для _ в 0..100_000_000 { сетка(18, 18, &mut memo); } println!("{}", start.elapsed().as_millis()); } Он по-прежнему примерно в четыре раза медленнее, чем Node.js.
узел index.js = 54
грузовой пробег --release = 236
Проблема решена, подробности в комментариях.
У меня есть функция с именем
сетка
который взят из задачи динамического программирования «grid Traveler». Я дважды написал одну и ту же функцию на JavaScript и Rust и протестировал 10 миллионов вычислений, запоминая обе функции.
JavaScript:
const Grid = (m, n, memo) => { константный ключ = m + ',' + n; if (ключ в заметке) вернуть memo[ключ] const max = Math.max(m, n) const min = Math.min(m, n) const d = Array.from({ length: max }, () => 1) for (пусть я = 1; я < min; я++) { for (let j = i; j < max; j++) { константный индекс = j если (я === j) { д[индекс] *= 2 } еще { d[индекс] = d[индекс] + d[индекс - 1] } } } памятка[ключ] = d[макс. - 1] вернуть d[макс - 1] } пусть старт = новая дата().getTime() константная заметка = {} для (пусть я = 0; я < 10_000_000; я++) { // сетка(18, 18) сетка(18, 18, памятка) } console.log(новая дата().getTime() - начало) Ржавчина:
use std::collections::hash_map::Entry; используйте std::collections::HashMap; используйте std::time::SystemTime; fngrid(m: &usize, n: &usize, memo: &mut HashMap) -> u64 { let key = m.to_string() + "," + &n.to_string(); сопоставить memo.entry(ключ) { Entry::Occupied(x) => *x.get(), Запись::Вакант(v) => { пусть макс: &usize; пусть мин: &usesize; если м > п { макс = &м; мин = & п; } еще { Макс = &n; мин = &м; } пусть mut d = Vec::::with_capacity(*max); для _ в 0..*max { д.push(1); } для меня через 1..*мин { для j в i..*max { если я == j { д[j] *= 2; } еще { d[j] = d[j] + d[j - 1]; } } } v.insert(d[*max - 1]); вернуть d[*max - 1]; } } } fn main() { пусть start = SystemTime::now(); let mut memo = HashMap::::new(); пусть т = 18; пусть n = 18; для _ через 0..10_000_000 { сетка(&m, &n, &mut memo); // сетка(&m, &n); } println!("{}", start.elapsed().unwrap().as_millis()); } Результаты тестирования с помощью команд:
узел index.js = 9
грузовой пробег --release = 1614
Я подумал, что, возможно, использование хэш-карты — не такая уж хорошая идея, поэтому попробовал макрос #[memoize] из этого ящика.
Результаты оказались разочаровывающими:
узел index.js = 9
грузовой пробег --release = 254
Почему это происходит и как лучше всего запомнить эту функцию в Rust?
Также результаты тестов без запоминания:
узел index.js = 15424
грузовой пробег --release = 2400
(Изменения от Хаима Фридмана) + (переход на 100 миллионов звонков):
Ржавчина:
use std::collections::hash_map::Entry; используйте std::time::Instant; используйте Rustc_hash::FxHashMap; fngrid(m: usesize, n: usesize, memo: &mut FxHashMap) -> u64 { пусть ключ: (использовать, использовать) = (м, п); сопоставить memo.entry(ключ) { Entry::Occupied(x) => *x.get(), Запись::Вакант(v) => { пусть макс: &usize; пусть мин: &usesize; если м > п { макс = &м; мин = & п; } еще { Макс = &n; мин = &м; } пусть mut d = Vec::::with_capacity(*max); для _ в 0..*max { д.push(1); } для меня через 1..*мин { для j в i..*max { если я == j { д[j] *= 2; } еще { d[j] = d[j] + d[j - 1]; } } } v.insert(d[*max - 1]); вернуть d[*max - 1]; } } } fn main() { пусть start = Instant::now(); let mut memo = FxHashMap::::default(); для _ в 0..100_000_000 { сетка(18, 18, &mut memo); } println!("{}", start.elapsed().as_millis()); } Он по-прежнему примерно в четыре раза медленнее, чем Node.js.
узел index.js = 54
грузовой пробег --release = 236
Проблема решена, подробности в комментариях.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
ObservableCollections против ObservableObject против ObservableRecipient против ViewmodelBase?
Anonymous » » в форуме C# - 0 Ответы
- 74 Просмотры
-
Последнее сообщение Anonymous
-
-
-
ObservableCollections против ObservableObject против ObservableRecipient против ViewmodelBase?
Anonymous » » в форуме C# - 0 Ответы
- 58 Просмотры
-
Последнее сообщение Anonymous
-