|
3 | 3 | use std::cmp::min;
|
4 | 4 |
|
5 | 5 | #[cfg(feature = "bench")]
|
6 |
| -use test::Bencher; |
| 6 | +use test::{black_box, Bencher}; |
7 | 7 |
|
8 | 8 | use cast::{As, Truncate};
|
9 | 9 | use optimize::{total_encoded_len, Optimizer, Parser, Segment};
|
@@ -859,17 +859,20 @@ pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
|
859 | 859 | /// Finds the smallest version (QR code only) that can store N bits of data
|
860 | 860 | /// in the given error correction level.
|
861 | 861 | fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
|
862 |
| - let mut min = 0; |
863 |
| - let mut max = 39; |
864 |
| - while min < max { |
865 |
| - let half = (min + max) / 2; |
866 |
| - if DATA_LENGTHS[half][ec_level as usize] < length { |
867 |
| - min = half + 1; |
868 |
| - } else { |
869 |
| - max = half; |
870 |
| - } |
871 |
| - } |
872 |
| - Version::Normal((min + 1).as_i16()) |
| 862 | + let mut base = 0usize; |
| 863 | + let mut size = 39; |
| 864 | + while size > 1 { |
| 865 | + let half = size / 2; |
| 866 | + let mid = base + half; |
| 867 | + // mid is always in [0, size). |
| 868 | + // mid >= 0: by definition |
| 869 | + // mid < size: mid = size / 2 + size / 4 + size / 8 ... |
| 870 | + base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid }; |
| 871 | + size -= half; |
| 872 | + } |
| 873 | + // base is always in [0, mid) because base <= mid. |
| 874 | + base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 }; |
| 875 | + Version::Normal((base + 1).as_i16()) |
873 | 876 | }
|
874 | 877 |
|
875 | 878 | #[cfg(test)]
|
@@ -907,5 +910,19 @@ mod encode_auto_tests {
|
907 | 910 | }
|
908 | 911 | }
|
909 | 912 |
|
| 913 | +#[cfg(feature = "bench")] |
| 914 | +#[bench] |
| 915 | +fn bench_find_min_version(bencher: &mut Bencher) { |
| 916 | + bencher.iter(|| { |
| 917 | + black_box(find_min_version(60, EcLevel::L)); |
| 918 | + black_box(find_min_version(200, EcLevel::L)); |
| 919 | + black_box(find_min_version(200, EcLevel::H)); |
| 920 | + black_box(find_min_version(20000, EcLevel::L)); |
| 921 | + black_box(find_min_version(640, EcLevel::L)); |
| 922 | + black_box(find_min_version(641, EcLevel::L)); |
| 923 | + black_box(find_min_version(999999, EcLevel::H)); |
| 924 | + }) |
| 925 | +} |
| 926 | + |
910 | 927 | //}}}
|
911 | 928 | //------------------------------------------------------------------------------
|
0 commit comments