Merge pull request #28 from pickfire/branchless
Use branchless binary search to find_min_version
This commit is contained in:
commit
0a4c64842d
39
src/bits.rs
39
src/bits.rs
|
@ -3,7 +3,7 @@
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
#[cfg(feature = "bench")]
|
#[cfg(feature = "bench")]
|
||||||
use test::Bencher;
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
use cast::{As, Truncate};
|
use cast::{As, Truncate};
|
||||||
use optimize::{total_encoded_len, Optimizer, Parser, Segment};
|
use optimize::{total_encoded_len, Optimizer, Parser, Segment};
|
||||||
|
@ -859,17 +859,20 @@ pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
|
||||||
/// Finds the smallest version (QR code only) that can store N bits of data
|
/// Finds the smallest version (QR code only) that can store N bits of data
|
||||||
/// in the given error correction level.
|
/// in the given error correction level.
|
||||||
fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
|
fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
|
||||||
let mut min = 0;
|
let mut base = 0usize;
|
||||||
let mut max = 39;
|
let mut size = 39;
|
||||||
while min < max {
|
while size > 1 {
|
||||||
let half = (min + max) / 2;
|
let half = size / 2;
|
||||||
if DATA_LENGTHS[half][ec_level as usize] < length {
|
let mid = base + half;
|
||||||
min = half + 1;
|
// mid is always in [0, size).
|
||||||
} else {
|
// mid >= 0: by definition
|
||||||
max = half;
|
// mid < size: mid = size / 2 + size / 4 + size / 8 ...
|
||||||
}
|
base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
|
||||||
|
size -= half;
|
||||||
}
|
}
|
||||||
Version::Normal((min + 1).as_i16())
|
// base is always in [0, mid) because base <= mid.
|
||||||
|
base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
|
||||||
|
Version::Normal((base + 1).as_i16())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -907,5 +910,19 @@ mod encode_auto_tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bench")]
|
||||||
|
#[bench]
|
||||||
|
fn bench_find_min_version(bencher: &mut Bencher) {
|
||||||
|
bencher.iter(|| {
|
||||||
|
black_box(find_min_version(60, EcLevel::L));
|
||||||
|
black_box(find_min_version(200, EcLevel::L));
|
||||||
|
black_box(find_min_version(200, EcLevel::H));
|
||||||
|
black_box(find_min_version(20000, EcLevel::L));
|
||||||
|
black_box(find_min_version(640, EcLevel::L));
|
||||||
|
black_box(find_min_version(641, EcLevel::L));
|
||||||
|
black_box(find_min_version(999999, EcLevel::H));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//}}}
|
//}}}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue