1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 05:27:45 +00:00

tr: improve speed slightly

This commit is contained in:
Arcterus 2014-11-30 15:28:00 -08:00
parent f07fedfcf9
commit f628e70d4a

View file

@ -13,10 +13,9 @@
extern crate collections; extern crate collections;
extern crate getopts; extern crate getopts;
use collections::bitv_set::BitvSet;
use collections::vec_map::VecMap;
use getopts::OptGroup; use getopts::OptGroup;
use std::char::from_u32; use std::char::from_u32;
use std::collections::{BitvSet, VecMap};
use std::io::print; use std::io::print;
use std::io::stdio::{stdin,stdout}; use std::io::stdio::{stdin,stdout};
use std::iter::FromIterator; use std::iter::FromIterator;
@ -28,6 +27,7 @@ mod util;
static NAME : &'static str = "tr"; static NAME : &'static str = "tr";
static VERSION : &'static str = "1.0.0"; static VERSION : &'static str = "1.0.0";
#[inline]
fn unescape_char(c: char) -> char { fn unescape_char(c: char) -> char {
match c { match c {
'a' => 0x07u8 as char, 'a' => 0x07u8 as char,
@ -41,6 +41,7 @@ fn unescape_char(c: char) -> char {
} }
} }
#[inline]
fn unescape(v: Vec<char>) -> Vec<char> { fn unescape(v: Vec<char>) -> Vec<char> {
let mut out = Vec::new(); let mut out = Vec::new();
let mut input = v.as_slice(); let mut input = v.as_slice();
@ -60,6 +61,7 @@ fn unescape(v: Vec<char>) -> Vec<char> {
out out
} }
#[inline]
fn expand_range(from: char, to: char) -> Vec<char> { fn expand_range(from: char, to: char) -> Vec<char> {
range(from as u32, to as u32 + 1).map(|c| from_u32(c).unwrap()).collect() range(from as u32, to as u32 + 1).map(|c| from_u32(c).unwrap()).collect()
} }
@ -109,12 +111,16 @@ fn delete(set: Vec<char>, complement: bool) {
} }
fn tr(set1: &[char], set2: &[char]) { fn tr(set1: &[char], set2: &[char]) {
let mut map = VecMap::<char>::new(); const BUFFER_LEN: uint = 1024;
let mut out = stdout();
let mut map = VecMap::new();
let mut stdout = stdout();
let mut outbuffer = String::with_capacity(BUFFER_LEN);
let set2_len = set2.len();
for i in range(0, set1.len()) { for i in range(0, set1.len()) {
if i >= set2.len() { if i >= set2_len {
map.insert(set1[i] as uint, set2[set2.len()-1]); map.insert(set1[i] as uint, set2[set2_len - 1]);
} else { } else {
map.insert(set1[i] as uint, set2[i]); map.insert(set1[i] as uint, set2[i]);
} }
@ -127,22 +133,29 @@ fn tr(set1: &[char], set2: &[char]) {
Some(t) => *t, Some(t) => *t,
None => inc, None => inc,
}; };
out.write_char(trc).unwrap(); outbuffer.push(trc);
if outbuffer.len() >= BUFFER_LEN {
stdout.write_str(outbuffer.as_slice()).unwrap();
outbuffer.clear();
}
} }
Err(err) => { Err(err) => {
panic!("{}", err); panic!("{}", err);
} }
} }
} }
if outbuffer.len() > 0 {
stdout.write_str(outbuffer.as_slice()).unwrap();
}
} }
fn usage(opts: &[OptGroup]) { fn usage(opts: &[OptGroup]) {
println!("{} {}", NAME, VERSION); println!("{} {}", NAME, VERSION);
println!(""); println!("");
println!("Usage:"); println!("Usage:");
println!(" {} [OPTIONS] SET1 [SET2]", NAME); println!(" {} [OPTIONS] SET1 [SET2]", NAME);
println!(""); println!("");
print(getopts::usage("Translate or delete characters.", opts).as_slice()); print(getopts::usage("Translate or delete characters.", opts).as_slice());
} }
pub fn uumain(args: Vec<String>) -> int { pub fn uumain(args: Vec<String>) -> int {