#[cfg(not(debug_assertions))]
mod release {
use std::hint::black_box;
use std::time::{Duration, Instant};
use token_align::get_alignments;
#[test]
fn marker_shapes_scale_linearly_and_meet_the_release_ceiling() {
for shape in [Shape::Identical, Shape::WordPiece, Shape::SentencePiece] {
assert_growth(shape);
}
}
#[test]
fn accented_marker_shape_scales_linearly_and_meets_the_release_ceiling() {
assert_growth(Shape::SentencePieceAccent);
}
fn assert_growth(shape: Shape) {
let small = inputs(10_000, shape);
let large = inputs(100_000, shape);
let small_time = measure(&small, 5);
let large_time = measure(&large, 3);
let ratio = large_time.as_secs_f64() / small_time.as_secs_f64();
eprintln!("{shape:?}: 10k {small_time:?}, 100k {large_time:?}, ratio {ratio:.2}");
assert!(
ratio <= 15.0,
"{shape:?} growth ratio {ratio:.2} exceeds 15: {small_time:?} to {large_time:?}"
);
assert!(
large_time <= Duration::from_millis(250),
"{shape:?} took {large_time:?} for 100k source tokens"
);
}
fn measure(input: &(Vec<String>, Vec<String>), repetitions: usize) -> Duration {
let mut best = Duration::MAX;
for _ in 0..repetitions {
let start = Instant::now();
let result = get_alignments(black_box(&input.0), black_box(&input.1));
black_box(result);
best = best.min(start.elapsed());
}
best
}
#[derive(Clone, Copy, Debug)]
enum Shape {
Identical,
WordPiece,
SentencePiece,
SentencePieceAccent,
}
fn inputs(count: usize, shape: Shape) -> (Vec<String>, Vec<String>) {
let left: Vec<String> = match shape {
Shape::SentencePieceAccent => (0..count)
.map(|index| format!("café{}", index % 10))
.collect(),
_ => (0..count)
.map(|index| format!("word{}", index % 10))
.collect(),
};
let right = match shape {
Shape::Identical => left.clone(),
Shape::WordPiece => (0..count)
.flat_map(|index| ["wo".to_owned(), format!("##rd{}", index % 10)])
.collect(),
Shape::SentencePiece => (0..count)
.map(|index| format!("▁word{}", index % 10))
.collect(),
Shape::SentencePieceAccent => (0..count)
.map(|index| format!("▁cafe{}", index % 10))
.collect(),
};
(left, right)
}
}