I finished my program and it works! My threaded version works A LOT faster!!!!
So cool.
Here is the version with no threads (same code, but all thread-related code deleted).
/*
* The purpose of this program is to find a specific word
* and see how fast it goes.
*
*/
use std::path::Path;
use std::vec::Vec;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::{Duration, Instant};
/**
*
* Function to search for a specific word in a file.
*
* # Arguments
* * `word` - The word to search in file. (The needle).
* * `file` - The file to search in, is type std::vec::Vec. (The haystack).
* * `start` - Position to start searching from.
* * `end` - When this position is reached the search is discontinued.
*
* # Return
* Returns an integer representing the position where `word` is found.
* Returns -1 if `word` is not found.
*/
fn search_for_word(word: String, file: Vec<u8> , start: u64, end: u64) -> i64 {
// Checking if all parameters are valid
if start >= end {
panic!("Parameter `end` should have a bigger value than `start`! Aborting...");
}
if word.len() == 0 || word.contains(' ') {
panic!("Parameter `word` had an invalid value! Aborting...");
}
// Looping over all characters in file starting from `start` to `end`
let mut word_buffer : String = String::new();
for i in start..end {
let character: char = file[i as usize] as char;
// If character is a space (AKA a word has passed) or end of
// file is reached: check if word matches with our needle.
if character == ' ' || i+1 == file.len() as u64 {
if word_buffer == word {
// Matches!
//println!("{} is found at position {}!", word, 1+i-word.len() as u64);
return i as i64; // ??
}
word_buffer.clear();
continue;
}
// Appending character to word until space (AKA end of word)
word_buffer.push(character);
};
-1
}
fn main() {
// Timing how long this program takes to execute
let now = Instant::now();
// Path to file, and file read into memory (std::vec::Vec)
let path : &Path = Path::new("src/file.txt");
let file = std::fs::read(path).expect("File not found...");
// Word to search
let word : String = "myneedle".to_string();
// Amount of chars in file
let length : u64 = file.len() as u64;
let x = search_for_word(word.clone(), file, 0, length);
println!("{} is found at position {}!", word, x);
println!("Program finished in {} ms", now.elapsed().as_millis());
}
And this is the super fast threaded version!!
/*
* The purpose of this program is to find a specific word
* in a text file very fast. To achieve this we use threads.
*
*/
use std::path::Path;
use std::vec::Vec;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::{Duration, Instant};
/**
*
* Function to search for a specific word in a file.
*
* # Arguments
* * `word` - The word to search in file. (The needle).
* * `file` - The file to search in, is type std::vec::Vec. (The haystack).
* * `start` - Position to start searching from.
* * `end` - When this position is reached the search is discontinued.
*
* # Return
* Returns an integer representing the position where `word` is found.
* Returns -1 if `word` is not found.
*/
fn search_for_word(word: String, file: Vec<u8> , start: u64, end: u64) -> i64 {
// Checking if all parameters are valid
if start >= end {
panic!("Parameter `end` should have a bigger value than `start`! Aborting...");
}
if word.len() == 0 || word.contains(' ') {
panic!("Parameter `word` had an invalid value! Aborting...");
}
// Looping over all characters in file starting from `start` to `end`
let mut word_buffer : String = String::new();
for i in start..end {
let character: char = file[i as usize] as char;
// If character is a space (AKA a word has passed) or end of
// file is reached: check if word matches with our needle.
if character == ' ' || i+1 == file.len() as u64 {
if word_buffer == word {
// Matches!
//println!("{} is found at position {}!", word, 1+i-word.len() as u64);
return i as i64; // ??
}
word_buffer.clear();
continue;
}
// Appending character to word until space (AKA end of word)
word_buffer.push(character);
};
-1
}
fn main() {
// Timing how long this program takes to execute
let now = Instant::now();
// Path to file, and file read into memory (std::vec::Vec)
let path : &Path = Path::new("src/file.txt");
let file = std::fs::read(path).expect("File not found...");
// Word to search
let word : String = "myneedle".to_string();
// Amount of chars in file
let length : u64 = file.len() as u64;
// Dividing in four chuncks to divide over the four threads
let mut one_fourth : u64 = length / 4;
// In special scenario where our file is so small that
// `one_fourth` results in being smaller than the length of
// the word, make chuncks smaller.
if one_fourth <= word.len() as u64 {
one_fourth = word.len() as u64 -1;
}
// Vector holding threads
let mut threads = Vec::new();
// Vector holding all returns from `search_for_word`
let mut search_for_word_return_values : Arc<Mutex<Vec<i64>>> = Arc::new(Mutex::new(Vec::new()));
// Variable holding position where word is found
let mut word_found_at : i64 = -1;
// Making four separate threads calling the `search_for_word` function
for i in 0..4 {
let file = file.clone();
let word = word.clone();
// Determing start and end of this chunck
let start : u64 = i * one_fourth;
let mut end : u64 = (i+1) * one_fourth + (word.len() -1) as u64;
if end > file.len() as u64 || i == 3 {
end = file.len() as u64;
}
let mut search_for_word_return_values = search_for_word_return_values.clone();
let thread = std::thread::spawn(move || {
let x = search_for_word(word.clone(), file, start, end);
search_for_word_return_values.lock().unwrap().push(x);
});
threads.push(thread);
}
// Waiting for all threads to finish
for thread in threads {
let x = thread.join().expect("Unknown thread error occured.");
}
// Highest value (AKA the only value not -1) will be the position
// where the word is found. Only the thread who found the word will not return -1
for val in search_for_word_return_values.lock().unwrap().iter() {
if *val != -1 {
word_found_at = 1 + *val - word.len() as i64;
}
}
println!("{} is found at position {}!", word, word_found_at);
println!("Program finished in {} ms", now.elapsed().as_millis());
}
I've used a famous textfile called alice29.txt (152kb) and placed the word "myneedle" somewhere near the end.
My threaded version can find this word in less than 7ms while the non-threaded version sometimes even take 20ms!!!!!!! That literally is close to 4 times faster!!