- Rust의 대표 난수 크레이트
rand는 일상적인 연산이 여러 특성에 흩어져 있어, 더 작은 공개·구현 표면과 일관된 사용 경험을 갖춘 urandom을 개발함 - 고수준 연산을 하나의
Random구조체에 모으고Rng특성을 봉인해, 임의 생성기 지원보다 API 발견성과 내부 최적화를 우선함 - 새로운 난수 알고리듬을 도입하지 않고 Xoshiro256의 출력 함수를 용도별로 선택해, 1,000개
f64생성 벤치마크에서rand0.10.2보다 약 31% 높은 처리량을 기록함 - 균등 정수 표본 추출은 임계값을 지연 계산하는 하나의 비편향 구현으로 재사용·일회성 경로를 통합했으며,
500..20_000범위 벤치마크에서rand의 두 경로보다 빨랐음 - 명시적 시드의 원시 출력은 지원 아키텍처와 SemVer 호환 릴리스에서 재현성을 보장하지만, 임의 생성기 연결과
rand의 방대한 분포·서드파티 통합 생태계는 포기함
하나로 모은 Random API
rand의 유용한 연산은 여러 특성에 흩어져 있음- 난수 범위 생성에는
RngExt, 시퀀스 선택에는IndexedRandom, 섞기에는SliceRandom이 필요함 rand0.10은 일회성 호출을 위한rand::random_range같은 루트 수준 도우미를 제공함- RNG 핸들을 유지하거나 선택·섞기 같은 시퀀스 연산을 사용하려면 여전히 여러 특성의 메서드를 찾아야 함
- 난수 범위 생성에는
- prelude로 가져오기를 줄여도 확장 메서드가 RNG, 슬라이스, 반복자 중 어느 타입에 적용되는지 알아야 하므로 IDE 자동 완성만으로 찾기 어려움
- urandom은 고수준 소비자 API를 하나의
Random래퍼 구조체에 배치함urandom::new()로Random<urandom::rng::Xoshiro256Rng>를 생성함uniform,choose,shuffle을 같은 객체에서 호출할 수 있음- 자동 완성으로
random,uniform,chance,choose,shuffle,sample등을 확인할 수 있음 - 모두 고유 메서드이므로 고수준 확장 특성을 찾거나 가져올 필요가 없음
확장성 대신 최적화를 택한 봉인된 Rng
rand는 저수준 RNG 특성을 공개 확장 지점으로 취급하지만,urandom의Rng특성은 봉인되어 지원 생성기를 크레이트 내부에서 선택하고 구현함- 임의 생성기를
Random에 연결할 수 없음 - 새 생성기를 추가하려면
urandom자체를 변경해야 함
- 임의 생성기를
- 더 나은 알고리듬이 목적이라면 현재 역할별 기본 선택으로 Xoshiro256과 ChaCha가 이미 자리 잡고 있으며, 권장 사항도 천천히 바뀜
- 더 나은 선택지가 생기면 향후 메이저 릴리스에서 채택할 수 있음
- 다른 프로젝트·프로그래밍 언어·레거시 알고리듬·특수 하드웨어·시뮬레이션 전용 생성기와 호환하려면 생성기만 같아서는 부족함
- 균등 표본 추출과 섞기 등 관련 알고리듬까지 같아야 하므로 전체 계약을 구현한 전용 구현이 더 적합함
- 봉인된 특성 덕분에 알 수 없는 생성기와 예외 상황을 위한 구현 계약을 설계·문서화하지 않고
urandom에 필요한 원시 연산만 추가할 수 있음- 생성기와 알고리듬을 서로 맞춰 특수화할 수 있어
rand에서는 사용할 수 없는 일부 최적화가 가능함
- 생성기와 알고리듬을 서로 맞춰 특수화할 수 있어
- 대부분의 애플리케이션에서는 새 PRNG 구현보다 엔트로피 선택이 더 유용함
- 구체적인 생성기는 네이티브
from_seed생성자를 공개함 ChaCha12Rng::from_seed(seed)처럼 명시적 시드를 사용한Random을 만들 수 있음- 임의 RNG 구현은 받지 않지만 고급 사용자가 필요로 할 것으로 예상되는 확장 지점은 유지함
- 구체적인 생성기는 네이티브
같은 알고리듬에서 얻은 성능 향상
urandom은 새로운 난수 생성 알고리듬을 사용하지 않음- 64비트 시스템에서 비암호학적 용도의
urandom::new()와rand::rngs::SmallRng은 같은 Xoshiro256 계열을 사용함 - 암호학적 용도의
urandom::csprng()와rand::rngs::StdRng은 ChaCha12를 사용함 - 편의 함수
rand::rng()의 내부 생성기도 ChaCha12임
- 64비트 시스템에서 비암호학적 용도의
rand의 생성기 인터페이스는 정수 워드와 바이트 채우기를 제공하므로f64가 필요한 분포도 전체u64부터 요청함urandom::Rng은next_u32,next_u64뿐 아니라next_f32와next_f64도 제공함- 부동소수점 난수는 전체 워드보다 적은 난수 비트가 필요함
- 생성기는 이 메서드들을 더 저렴한 출력 함수로 재정의할 수 있음
- Xoshiro 구현은 상태 전이를 공유하면서 출력 경로를 구분함
u64에는 Xoshiro256++를 유지함u32와 부동소수점에는 상위 비트가 해당 용도에 맞게 설계된 더 빠른 Xoshiro256+를 사용함
urandom1.0과rand0.10.2로 각각 1,000개의 난수를 생성한 마이크로벤치마크 결과는 다음과 같음- Xoshiro
u64: 양쪽 모두 814ns - Xoshiro
u32:rand836ns,urandom788ns - Xoshiro
f64:rand1,033ns,urandom788ns - ChaCha12
f64:rand2,199ns,urandom2,011ns
- Xoshiro
- Xoshiro
f64의 종단 간 처리량은 약 31% 높고 실행 시간은 24% 짧았지만, 동일한 작업을 수행하는u64경로는 사실상 동률이었음 - ChaCha12는
next_f64를 재정의하지 않아 성능이 대체로 비슷함 - 정확한 시간은 머신과 컴파일러에 따라 달라지며, 자세한 조건은 전체 벤치마크 노트에서 확인할 수 있음
하나로 통합한 균등 표본 추출 경로
- 정수를 범위 길이로 단순 나머지 연산하면 편향이 생기므로, 올바른 균등 정수 표본 추출은 생성기 출력 일부를 거부해야 함
- 정확한 거부 임계값 계산에는 비용이 큰 나머지 연산이 필요함
- 표본 추출기를 반복 사용한다면 초기 설정 비용으로 감당할 수 있음
- 값 하나만 생성할 때는 이 비용이 상대적으로 커짐
rand는 이러한 차이를UniformSampler특성으로 노출함- 생성된
UniformInt는 임계값을 미리 계산해 편향 없이 표본을 추출함 Rng::random_range는 초기 설정을 피하려고 별도의sample_single또는sample_single_inclusive훅을 사용함- 기본 기능에서는 일회성 단축 경로가 조금 편향된 두 번째 알고리듬을 사용함
- 선택적
unbiased기능은 이를 더 복잡한 반복 버전으로 교체함
- 생성된
urandom은 임계값을 지연 계산해 재사용 및 일회성 범위 모두에 하나의 비편향 곱셈·거부 구현을 사용함- Daniel Lemire의 2018년 논문 Fast Random Integer Generation in an Interval에 기술된 방식을 따름
- 대부분의 실용적 범위에서는 첫 후보가 나눗셈 전에 반환됨
- 첫 후보를 반환할 수 없으면 정확한 임계값을 계산한 뒤 편향 없이 반복함
- 전체 범위가 요청되는
range == 0예외도 처리함
- 별도 메서드나 두 번째 알고리듬, 선행 설정 비용, 편향된 고속 경로 없이 동일한 구현으로 재사용 분포와 일회성 범위를 처리함
500..20_000범위에서 1,000개를 추출한 벤치마크 결과는 다음과 같음- 재사용
UniformInt:rand1,098ns,urandom950ns - 일회성 범위:
rand1,079ns,urandom942ns
- 재사용
rand결과는 기본 기능 기준이므로 더 빠른 일회성 행도 약간 편향된 경로인 반면,urandom은 비편향 상태로 두 경로보다 빨랐음
릴리스와 아키텍처를 아우르는 재현성
urandom은 재현성을 공개 계약의 일부로 취급함- 같은 명시적 시드와 같은 저수준 RNG 호출 순서가 주어지면 결정론적 생성기의 원시 출력이 유지됨
- 지원 아키텍처와 SemVer 호환 릴리스 전체에서 안정성을 보장함
- 64비트 서버와 32비트 WebAssembly 클라이언트가 재생을 위한 동일한 생성기 기반을 사용할 수 있음
- 이 호환성을 유지하기 위해 32비트 아키텍처에서는 성능을 희생함
rand의 재현성 정책보다 강한 보장임rand의 이식 가능한 생성기와 표본 추출 알고리듬은 마이너 릴리스에서 출력이 달라질 수 있음SmallRng과StdRng은 명시적으로 이식 가능하지 않으며 플랫폼이나 라이브러리 릴리스에 따라서도 바뀔 수 있음
선택의 대가와 적용 기준
urandom은 일반 연산을Random에 모아 확장 특성 없이 쉽게 찾을 수 있게 함- 생성기와 분포를 함께 설계해 더 저렴한 Xoshiro 출력 경로와 하나의 비편향 균등 표본 추출 경로를 구현함
- 명시적으로 시드가 지정된 생성기의 안정적인 원시 스트림은 결정론적 게임과 시뮬레이션에 활용할 수 있음
- 대신 임의 생성기를 가져올 수 없으며,
rand가 제공하는 더 큰 분포 목록과 서드파티 통합 생태계도 갖추지 못함 - 광범위한 생태계가 필요하면
rand가 적합하고, 작은 API 표면·발견성·통합된 최적화·강한 재현성 정책을 선호하면urandom을 선택할 수 있음 - 패키지는 crates.io, API 문서, GitHub 소스에서 확인할 수 있음