История изменений
Исправление khrundel, (текущая версия) :
Мой адаптированный вариант со скипвайлами:
use std::fs;
use std::fs::File;
use std::io::prelude::*;
struct Lexer<'a>{
left: &'a str
}
impl<'a> Lexer<'a>{
fn new(source:&'a str)->Lexer<'a> {
Lexer{left : source}
}
fn next (&mut self) -> Option<&'a str> {
let iter = self.left.char_indices();
let mut iter = iter.skip_while(|i| i.1 == ' ');
if let Some((start_index, c)) = iter.next() {
let end_index = match c {
'A'...'Z' | 'a'...'z' => if let Some((e, _)) = iter
.skip_while(|i| i.1 >= 'A' && i.1 <= 'Z' || i.1 >= 'a' && i.1 <= 'z')
.next() { e } else { self.left.len() },
_ => if let Some((e, _)) = iter.next() { e } else { self.left.len() },
};
let t = self.left;
self.left = &t[end_index..];
return Some(&t[start_index..end_index]);
}
None
}
}
fn main() {
let metadata = fs::metadata("data").unwrap();
let mut f = File::open("data").expect("file not found.");
let mut text = String::with_capacity(metadata.len() as usize);
f.read_to_string(&mut text)
.expect("error reading file.");
let mut lexer = Lexer::new(&text);
let mut commas_count = 0;
let mut words_count = 0;
while let Some(token) = lexer.next() {
if token.chars().next() == Some(',') {
commas_count += 1;
} else {
words_count += 1;
}
}
println!("Итого: {} слов и {} запятых", words_count, commas_count);
}
Размер файла в 100 раз увеличил, чтоб время более-менее нормально занимало.
Результат:
~/rust-workspace/rust-lexer$ time ./clexer
Итого: 350000001 слов и 250000000 запятых
real 0m9,187s
user 0m8,153s
sys 0m1,024s
~/rust-workspace/rust-lexer$ time ./target/release/rust-lexer
Итого: 350000001 слов и 250000000 запятых
real 0m9,733s
user 0m8,106s
sys 0m1,619s
Исходная версия khrundel, :
Мой адаптированный вариант со скипвайлами:
use std::fs;
use std::fs::File;
use std::io::prelude::*;
struct Lexer<'a>{
left: &'a str
}
impl<'a> Lexer<'a>{
fn new(source:&'a str)->Lexer<'a> {
Lexer{left : source}
}
fn next (&mut self) -> Option<&'a str> {
let iter = self.left.char_indices();
let mut iter = iter.skip_while(|i| i.1 == ' ');
if let Some((start_index, c)) = iter.next() {
let end_index = match c {
'A'...'Z' | 'a'...'z' => if let Some((e, _)) = iter
.skip_while(|i| i.1 >= 'A' && i.1 <= 'Z' || i.1 >= 'a' && i.1 <= 'z')
.next() { e } else { self.left.len() },
_ => if let Some((e, _)) = iter.next() { e } else { self.left.len() },
};
let t = self.left;
self.left = &t[end_index..];
return Some(&t[start_index..end_index]);
}
None
}
}
fn main() {
let metadata = fs::metadata("data").unwrap();
let mut f = File::open("data").expect("file not found.");
let mut text = String::with_capacity(metadata.len() as usize);
f.read_to_string(&mut text)
.expect("error reading file.");
let mut lexer = Lexer::new(&text);
let mut commas_count = 0;
let mut words_count = 0;
while let Some(token) = lexer.next() {
if token.chars().next() == Some(',') {
commas_count += 1;
} else {
words_count += 1;
}
}
println!("Итого: {} слов и {} запятых", words_count, commas_count);
}
Размер файла в 100 раз увеличил, чтоб время более-менее нормально занимало.
Результат:
~/rust-workspace/rust-lexer$ time ./clexer
Итого: 350000001 слов и 250000000 запятых
real 0m9,187s
user 0m8,153s
sys 0m1,024s
~/rust-workspace/rust-lexer$ time ./target/release/rust-lexer
Итого: 350000001 слов и 250000000 запятых
real 0m9,733s
user 0m8,106s
sys 0m1,619s