2015-08-18 2 views
2

Каков наилучший способ проверить хэш-карту для ключа? В настоящее время я использую это:Почему этот поиск hashmap медленнее, чем ожидалось?

let hashmap = HashMap::<&str, &str>::new(); // Empty hashmap 

let name = "random"; 

for i in 0..5000000 { 
    if !hashmap.contains_key(&name) { 
     // Do nothing 
     } 
} 

Это, кажется, быстро в большинстве случаев и занимает 0.06 секунды при запуске, как показано на рисунке, но когда я использую его в этом следующем цикле он становится очень медленно и занимает почти 1 мин на моя машина. (Это компиляция с cargo run --release). Код предназначен для открытия внешней программы и циклического вывода из этой программы.

let a = vec!["view", "-h"]; // Arguments to open process with 
let mut child = Command::new("samtools").args(&a) 
             .stdout(Stdio::piped()) 
             .spawn() 
             .unwrap(); 

let collect_pairs = HashMap::<&str, &str>::new(); 

if let Some(ref mut stdout) = child.stdout { 
    for line in BufReader::new(stdout).lines() { 
     // Do stuff here   
     let name = "random"; 
     if !collect_pairs.contains_key(&name) { 
      // Do nothing 
     } 
    } 
} 

По какой-то причине, добавляющий if !collect_pairs.contains_key( линии увеличивает время работы почти на минуту. Результат от ребенка составляет около 5 миллионов строк. Все это код существует в fn main()

EDIT

Это, кажется, решить эту проблему, в результате чего быстрое время выполнения, но я не знаю, почему !hashmap.contains_key не работает хорошо здесь:

let n: Option<&&str> = collect_pairs.get(name); 
if match n {Some(v) => 1, None => 0} == 1 { 
    // Do something 
} 
+1

Это займет 152 миллисекунды на моей машине. Собираетесь ли вы с оптимизацией? – Shepmaster

+0

Спасибо, я только что понял, что происходит что-то странное, но не пытайтесь перефразировать вопрос. – kezzos

ответ

3

Следует учитывать, что HashMap<K, V> использует криптографически безопасный алгоритм хэширования по умолчанию, поэтому он всегда будет немного медленным по своей природе.

get() сводится к

self.search(k).map(|bucket| bucket.into_refs().1) 

contains_key является

self.search(k).is_some() 

Как таковой, что get() быстрее для вас мне кажется странным, что он делает больше работы!

Кроме того,

if match n {Some(v) => 1, None => 0} == 1 { 

Это можно записать более идиоматически в

if let Some(v) = n { 
+0

Спасибо, есть ли способ изменить алгоритм хэширования, чтобы получить больше скорости? – kezzos

+0

@kezzos: В конечном счете, должно быть, однако все, что касается «Хашера», все еще нестабильно. –

0

Ive нашел мою проблему, Im жаль, что я не забрать вратаря до сих пор. Я не проверял возврат if !collect_pairs.contains_key(&name) должным образом. Он возвращает true по какой-либо причине, приводящей к остальной части выполняемого блока if. Я предположил, что он оценивает false. Спасибо за помощь

Смежные вопросы