Skip to content

Commit

Permalink
Binary: Report in markdown table format.
Browse files Browse the repository at this point in the history
Always count lines; slows down the read/batch tests.
  • Loading branch information
Freaky committed Apr 22, 2018
1 parent fe3db87 commit 5f5f89b
Showing 1 changed file with 108 additions and 45 deletions.
153 changes: 108 additions & 45 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,111 +6,174 @@ use std::time::{Duration, Instant};

extern crate linereader;
use linereader::LineReader;
extern crate memchr;

use memchr::Memchr;

const BUFFER_SIZE: usize = 1024 * 1024;

fn report(name: &str, lines: usize, bytes: usize, elapsed: Duration) {
let elapsed =
(elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0);
println!(
"{}: {} lines {} bytes in {:.2}s ({:.2} MB/s)",
name,
lines,
bytes,
elapsed,
((bytes as f64) / elapsed) / (1024.0 * 1024.0)
);
struct Report {
lines: u64,
bytes: u64,
}

fn try_baseline(filename: &str) {
impl Report {
fn new(filename: &str) -> Self {
let mut infile = File::open(filename).expect("open");

let mut lines = 0_u64;
let mut bytes = 0_u64;
let mut buf = [0; BUFFER_SIZE];
while let Ok(r) = infile.read(&mut buf[..]) {
if r == 0 {
break;
}
bytes += r as u64;
lines += Memchr::new(b'\n', &buf[..r]).count() as u64;
}

println!("File: {}, bytes: {}, lines: {}", filename, bytes, lines);

println!(
"| {:16} | {:^7} | {:^11} | {:^13} |",
"Method", "Time", "Lines/sec", "Bandwidth"
);
println!("|------------------|--------:|------------:|--------------:|");
Self { lines, bytes }
}

fn report(&self, name: &str, bytes: u64, lines: u64, elapsed: Duration) {
if bytes != self.bytes {
println!("Warning: expected {} bytes, read {}", self.bytes, bytes);
}

if lines != self.lines {
println!("Warning: expected {} lines, read {}", self.lines, lines);
}

let elapsed =
(elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0);
println!(
"| {:16} | {: >6.2}s | {:>9.0}/s | {:>8.2} MB/s |",
name,
elapsed,
(self.lines as f64) / elapsed,
((self.bytes as f64) / elapsed) / (1024.0 * 1024.0)
);
}
}

fn try_baseline(report: &Report, filename: &str) {
let mut infile = File::open(filename).expect("open");

let start = Instant::now();
let mut bytes = 0;
let mut bytes = 0_u64;
let mut lines = 0_u64;

let mut buf = [0; 1024 * 128];
let mut buf = [0; BUFFER_SIZE];
while let Ok(r) = infile.read(&mut buf[..]) {
if r == 0 {
break;
}
bytes += r;
bytes += r as u64;
lines += Memchr::new(b'\n', &buf[..r]).count() as u64;
}

report("128k blocks", 0, bytes, start.elapsed());
report.report("read() 1 MiB", bytes, lines, start.elapsed());
}

fn try_linereader(filename: &str) {
fn try_linereader_batch(report: &Report, filename: &str) {
let infile = File::open(filename).expect("open");

let mut reader = LineReader::with_capacity(BUFFER_SIZE, infile);

let start = Instant::now();
let mut count = 0;
let mut bytes = 0;
let mut lines = 0_u64;
let mut bytes = 0_u64;
while let Some(batch) = reader.next_batch() {
let batch = batch.unwrap();
bytes += batch.len() as u64;
lines += Memchr::new(b'\n', batch).count() as u64;
}

report.report("LR::next_batch()", bytes, lines, start.elapsed());
}

fn try_linereader(report: &Report, filename: &str) {
let infile = File::open(filename).expect("open");

let mut reader = LineReader::with_capacity(BUFFER_SIZE, infile);

let start = Instant::now();
let mut lines = 0_u64;
let mut bytes = 0_u64;
while let Some(line) = reader.next_line() {
bytes += line.unwrap().len();
count += 1;
bytes += line.unwrap().len() as u64;
lines += 1;
}

report("LineReader", count, bytes, start.elapsed());
report.report("LR::next_line()", bytes, lines, start.elapsed());
}

fn try_read_until(filename: &str) {
fn try_read_until(report: &Report, filename: &str) {
let infile = File::open(filename).expect("open");
let mut infile = BufReader::with_capacity(BUFFER_SIZE, infile);

let start = Instant::now();
let mut count = 0;
let mut bytes = 0;
let mut lines = 0_u64;
let mut bytes = 0_u64;
let mut line: Vec<u8> = Vec::with_capacity(128);
while infile.read_until(b'\n', &mut line).unwrap_or(0) > 0 {
bytes += line.len();
count += 1;
bytes += line.len() as u64;
lines += 1;
line.clear();
}

report("read_until", count, bytes, start.elapsed());
report.report("read_until()", bytes, lines, start.elapsed());
}

fn try_read_line(filename: &str) {
fn try_read_line(report: &Report, filename: &str) {
let infile = File::open(filename).expect("open");
let mut infile = BufReader::with_capacity(BUFFER_SIZE, infile);

let start = Instant::now();
let mut count = 0;
let mut bytes = 0;
let mut lines = 0_u64;
let mut bytes = 0_u64;
let mut line = String::new();
while infile.read_line(&mut line).unwrap_or(0) > 0 {
bytes += line.len();
count += 1;
bytes += line.len() as u64;
lines += 1;
line.clear();
}

report("read_line", count, bytes, start.elapsed());
report.report("read_line()", bytes, lines, start.elapsed());
}

fn try_lines_iter(filename: &str) {
fn try_lines_iter(report: &Report, filename: &str) {
let infile = File::open(filename).expect("open");
let infile = BufReader::with_capacity(BUFFER_SIZE, infile);

let start = Instant::now();
let mut bytes = 0;
let mut count = 0;
let mut lines = 0_u64;
let mut bytes = 0_u64;
for line in infile.lines() {
bytes += line.unwrap().len();
count += 1;
bytes += line.unwrap().len() as u64;
lines += 1;
}

report("lines()", count, bytes, start.elapsed());
report.report("lines()", bytes, lines, start.elapsed());
}

fn main() {
use std::env;

for file in env::args().skip(1) {
try_baseline(&file);
try_linereader(&file);
try_read_until(&file);
try_read_line(&file);
try_lines_iter(&file);
let report = Report::new(&file);
try_baseline(&report, &file);
try_linereader_batch(&report, &file);
try_linereader(&report, &file);
try_read_until(&report, &file);
try_read_line(&report, &file);
try_lines_iter(&report, &file);
}
}

0 comments on commit 5f5f89b

Please sign in to comment.