Chciałbym porównawczych niektórych operacji w Rust, ale wydaje się mieć pewne problemy:ciągi generowania i identyfikowania podciągi jest bardzo powolny
fn main(){
let needle = (0..100).map(|_| "b").collect::<String>();
let haystack = (0..100_000).map(|_| "a").collect::<String>();
println!("Data ready.");
for _ in 0..1_000_000 {
if haystack.contains(&needle) {
// Stuff...
}
}
}
Powyższy zajmuje bardzo dużo czasu, aby zakończyć podczas gdy ta sama operacja w Ruby zakończy w około 4,5 sekundy:
needle = 'b' * 100
haystack = 'a' * 100_000
puts 'Data ready.'
1_000_000.times do
haystack.include? needle
end
nie mogę pomóc, ale myślę, że robię coś fundamentalnie złego. Jaki byłby właściwy sposób robienia tego w Rust?
rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
Dla tych, którzy zastanawiać: w tym przypadku, to nie jest problem optymalizacji. Nawet przy włączonych optymalizacjach wersja rdzy jest wciąż bardzo długa. – Levans
Ja * myślę, że * może być tak, że 'zawiera' dla łańcuchów przyjmuje dodatkowe akcje by poprawnie obsługiwać UTF-8, jednak kiedy poszedłem sprawdzić prędkość 'zawiera' dla zwykłych plasterków dowiedziałem się, że Rust nie ma nawet jednego o_O. Moja naiwna implementacja wciąż była bardzo powolna. –
Próbowałem tego dla siebie; Ruby zajęła 5 sekund, Rust wziął * 7 minut *. Szybki squiz poprzez implementację Rusta (patrz ['libcore/str/pattern.rs'] (https://github.com/rust-lang/rust/blob/1.0.0/src/libcore/str/pattern.rs# L390)) sprawia, że wygląda na to, że wyszukiwarka Rusta jest * całkowicie naiwna *. Jeśli implementacja Ruby robi cokolwiek, nawet sprytnie, nie byłoby wcale zaskakujące, że Rust jest znacznie wolniejszy. Tak czy inaczej, wygląda na godnego problemu z wydajnością. –