2017-01-12 15 views
5

Я разборе значения, разделенные табуляцией:Как ускорить UTF-8 обработки строк

pub fn parse_tsv(line: &str) -> MyType { 
    for (i, value) in line.split('\t').enumerate() { 
     // ... 
    } 
    // ... 
} 

perf сверху содержит str.find. Когда я смотрю в сгенерированном коде сборки, есть много работ, связанных с кодировкой UTF-8 символов в &str.

И относительно медленное наблюдение. Это занимает 99% времени выполнения.

Но найти \t Я не могу просто найти один байт \t в строке UTF-8.

Что я делаю неправильно? Что делает Rust stdlib неправильно?

Или, может быть, в Rust есть некоторая строковая библиотека, которая может представлять строки просто байтами «u8»? Но со всеми split(), find() и другими методами?

+1

Вы компиляцию с оптимизациями на? ('--release' с грузом) – huon

+0

@huon конечно – vladon

+0

Какая разница в скорости, если вы используете' '\ t" 'вместо этого? – Shepmaster

ответ

7

Пока ваша строка ASCII или вам не нужно сопоставлять скаляры UTF-8 (например, как в вашем случае, где вы ищете вкладки), вы можете просто рассматривать ее как байты с помощью метода as_bytes() и впоследствии работают на u8 символах (байтах) вместо char s (сканеры UTF-8). Это должно быть намного быстрее. С &[u8], который является slice, вы можете использовать методы, применимые к &str ломтикам как split(), find() и т.д.

let line = String::new(); 
let bytes = line.as_bytes(); 

pub fn parse_tsv(line: &[u8]) { 
    for (i, value) in line.split(|c| *c == b'\t').enumerate() { 

    } 
} 

fn main() { 
    let line = String::new(); 
    let bytes = line.as_bytes(); 

    parse_tsv(&bytes) 
} 
+0

wow, я могу использовать split на '& [u8]', я не знал об этом, спасибо! – vladon