Тема: Найшвидший спосіб завантажування текстових файлів
Завантажую текстові файли ось таким чином:
pub type MapOfIndexes = IndexMap<String, (Rc<usize>, Rc<usize>)>;
pub type DictTuple = (Rc<String>, Rc<String>, Rc<String>, Rc<String>, MapOfIndexes);
pub fn download_dictionaries(settings: &gio::Settings) ->
Result<HashMap<String, DictTuple>> {
// Завантаження лінгвістичних словників
let start_function = Instant::now();
let default_dict_paths: String = settings.string("current-dict-path").to_string();
let mut map_of_dicts: HashMap<String, DictTuple> = Default::default();
if default_dict_paths != ""{
for path in default_dict_paths.split('\n'){
if !path.is_empty(){
let file_paths = get_mvr_paths(path)
.with_context(|| format!("Can't get file paths: {}", path))?;
for file_path in file_paths{
let file_path_string = file_path.clone().display().to_string();
let mut lines = read_lines(file_path)
.with_context(|| format!("Can't read file path {}: ", file_path_string))?;
let mut dict_name = "".to_string();
let mut lang_pair = "".to_string();
let mut dict_descr = "".to_string();
let mut regex_key = "".to_string();
let mut dict_body = "".to_string();
let mut take_count = 0;
for line in lines.by_ref().flatten().take(4){
match take_count{
0 => dict_name = line,
1 => lang_pair = line,
2 => dict_descr = line,
3 => regex_key = line,
_ => unreachable!(),
};
take_count += 1;
}
// println!("Regex key: {}", regex_key.to_string());
// println!("Dict name: {}", dict_name);
// println!("Lang pair: {}", lang_pair);
// println!("Dict descr: {}", dict_descr);
for line in lines.flatten(){
dict_body += format!("{line}\n").as_str();
}
let dict_indexes: MapOfIndexes =
create_dict_indexes(&dict_body, ®ex_key)?;
// println!("{}", dict_body);
map_of_dicts.insert(dict_name, (
Rc::new(lang_pair), Rc::new(dict_descr),
Rc::new(regex_key), Rc::new(dict_body), dict_indexes)
);
}
}
}
}
let duration = start_function.elapsed();
println!("Dictionaries downloading time: {:#?}", duration);
Ok(map_of_dicts)
}
fn get_mvr_paths(dir: &str) -> Result<Vec<PathBuf>> {
let paths = read_dir(dir)?
// Filter out all those directory entries which couldn't be read
.filter_map(|res| res.ok())
// Map the directory entries to paths
.map(|dir_entry| dir_entry.path())
// Filter out all paths with extensions other than `mvr`
.filter_map(|path| {
if path.extension().map_or(false, |ext| ext == "mvr"){
Some(path)
} else {
None
}
})
.collect::<Vec<_>>();
Ok(paths)
}
fn read_lines<P>(filename: P) -> Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
fn create_dict_indexes(dict_body: &String, regex_key: &String) ->
Result<MapOfIndexes>{
let mut words_indexes: MapOfIndexes = Default::default();
let re = Regex::new(regex_key).with_context(|| format!("Failed to create regex key {}", regex_key))?;
let words = re.find_iter(&dict_body);
for word in words{
let word_str = word.clone()?.as_str().to_string();
let word_start = word.clone()?.start().try_into()?;
let word_end = word.clone()?.end().try_into()?;
words_indexes.insert(word_str, (Rc::new(word_start), Rc::new(word_end)));
// println!("{} {} {}", word.unwrap().as_str(), word_start, word_end);
}
/*for (key, value) in &words_indexes{
let (start, end) = words_indexes.get(key.as_str()).unwrap();
let (start, end) = value;
println!("{} {} {}", key.to_string(), start, end);
}*/
/*for index in 0..words_indexes.len(){
let (word, (word_start, word_end)) =
words_indexes.get_index(index).unwrap();
println!("{}, {}, {}", word, word_start, word_end);
}*/
Ok(words_indexes)
}
Але завантаження одного словника займає цілих 12 секунд,
у той час як в С++(Qt) за 10 секунд завантажується 18 словників.
Чи є спосіб пришвидшити завантаження текстових файлів?