如何在proptest中高效均匀生成指定范围u32值的Strategy?
高效均匀生成小于1000000的u32值的Proptest Strategy方案
最优方案:直接使用范围或between函数
Proptest原生支持将数值范围作为Strategy,这是最简洁、高效且能保证均匀采样的方式,完全替代你提到的两种不够理想的方法:
use proptest::prelude::*; // 方式1:直接用Rust的范围语法 let strategy = 0u32..1_000_000u32; // 方式2:使用num模块的between函数(语义更明确) let strategy = proptest::num::u32::between(0, 1_000_000);
这两种方式都会直接生成[0, 999999]区间内的u32值,既不需要过滤重试(避免prop_filter的效率损耗),也不会有取模导致的采样不均匀问题,是Proptest设计中针对这类需求的标准解法。
关于Rng::gen_range的使用
你提到的Rng::gen_range确实可以实现,但需要手动包装成Strategy,写法反而繁琐,不如上面的原生方案高效简洁。如果一定要用,示例代码如下:
use proptest::prelude::*; use rand::Rng; let strategy = Strategy::from_fn(|mut runner| { let mut rng = runner.rng(); Ok(rng.gen_range(0..1_000_000)) });
为什么不推荐你原来的两种方法
prop_filter:会不断生成超出范围的值并丢弃,当目标区间远小于u32的全范围时,重试次数会很多,严重影响生成效率。- 取模运算:由于u32的最大值(4294967295)不是1000000的整数倍,取模后前
4294967295 % 1000000 + 1个值的出现概率会略高于其他值,无法保证严格均匀。
内容的提问来源于stack exchange,提问作者nimble_ninja
相关产品推荐
相关产品推荐

