mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 18:24:09 +02:00
optimize line splitting
This commit is contained in:
parent
0a110dc0f0
commit
7bd667004b
3 changed files with 52 additions and 8 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tf_log_parser::{parse, GameEvent, RawEvent};
|
use tf_log_parser::{parse, GameEvent, RawEvent, LineSplit};
|
||||||
|
|
||||||
pub fn parse_benchmark(c: &mut Criterion) {
|
pub fn parse_benchmark(c: &mut Criterion) {
|
||||||
let input = read_to_string("test_data/log_2892242.log").unwrap();
|
let input = read_to_string("test_data/log_2892242.log").unwrap();
|
||||||
|
|
@ -26,8 +26,7 @@ pub fn parse_raw(c: &mut Criterion) {
|
||||||
let input = read_to_string("test_data/log_2892242.log").unwrap();
|
let input = read_to_string("test_data/log_2892242.log").unwrap();
|
||||||
c.bench_function("parse raw 2892242", |b| {
|
c.bench_function("parse raw 2892242", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
black_box(&input)
|
LineSplit::new(black_box(&input))
|
||||||
.split("L ")
|
|
||||||
.filter(|line| !line.is_empty())
|
.filter(|line| !line.is_empty())
|
||||||
.flat_map(RawEvent::parse)
|
.flat_map(RawEvent::parse)
|
||||||
.count();
|
.count();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use iai::black_box;
|
use iai::black_box;
|
||||||
use tf_log_parser::{parse, RawEvent};
|
use tf_log_parser::{LineSplit, parse, RawEvent};
|
||||||
|
|
||||||
static LOG: &str = include_str!("../test_data/log_2892242.log");
|
static LOG: &str = include_str!("../test_data/log_2892242.log");
|
||||||
|
|
||||||
|
|
@ -9,8 +9,7 @@ pub fn parse_benchmark() {
|
||||||
|
|
||||||
pub fn parse_raw() {
|
pub fn parse_raw() {
|
||||||
black_box(
|
black_box(
|
||||||
black_box(&LOG)
|
LineSplit::new(black_box(&LOG))
|
||||||
.split("L ")
|
|
||||||
.filter(|line| !line.is_empty())
|
.filter(|line| !line.is_empty())
|
||||||
.flat_map(RawEvent::parse)
|
.flat_map(RawEvent::parse)
|
||||||
.count(),
|
.count(),
|
||||||
|
|
|
||||||
50
src/lib.rs
50
src/lib.rs
|
|
@ -14,6 +14,7 @@ pub use raw_event::{RawEvent, RawEventType};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use memchr::memmem::{find_iter, FindIter};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
@ -73,8 +74,7 @@ pub fn parse_with_handler<Handler: EventHandler>(
|
||||||
),
|
),
|
||||||
Error,
|
Error,
|
||||||
> {
|
> {
|
||||||
let events = log
|
let events = LineSplit::new(log)
|
||||||
.split("L ")
|
|
||||||
.filter(|line| !line.is_empty())
|
.filter(|line| !line.is_empty())
|
||||||
.map(RawEvent::parse);
|
.map(RawEvent::parse);
|
||||||
|
|
||||||
|
|
@ -129,3 +129,49 @@ handler!(LogHandler {
|
||||||
medic_stats: PlayerHandler::<MedicStatsBuilder>,
|
medic_stats: PlayerHandler::<MedicStatsBuilder>,
|
||||||
class_stats: ClassStatsHandler,
|
class_stats: ClassStatsHandler,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pub struct LineSplit<'a> {
|
||||||
|
input: &'a str,
|
||||||
|
start: usize,
|
||||||
|
iter: FindIter<'a, 'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LineSplit<'a> {
|
||||||
|
pub fn new(input: &'a str) -> Self {
|
||||||
|
LineSplit {
|
||||||
|
input,
|
||||||
|
start: 0,
|
||||||
|
iter: find_iter(input.as_bytes(), b"L ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for LineSplit<'a> {
|
||||||
|
type Item = &'a str;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(next) => {
|
||||||
|
let line = &self.input[self.start..next];
|
||||||
|
self.start = next + 2;
|
||||||
|
Some(line)
|
||||||
|
},
|
||||||
|
None if self.start < self.input.len() => {
|
||||||
|
let line = &self.input[self.start..];
|
||||||
|
self.start = self.input.len();
|
||||||
|
Some(line)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_split() {
|
||||||
|
let input = std::fs::read_to_string("test_data/log_2892242.log").unwrap();
|
||||||
|
let split: Vec<_> = LineSplit::new(&input).collect();
|
||||||
|
let expected: Vec<_> = input.split("L ").collect();
|
||||||
|
assert_eq!(expected, split);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue