4 个版本 (2 个破坏性更改)
| 0.4.0 | 2024年1月23日 |
|---|---|
| 0.3.0 | 2023年12月12日 |
| 0.2.1 | 2020年7月20日 |
| 0.2.0 | 2020年7月19日 |
#30 in 缓存
每月996次下载
用于 5 个crate (4 个直接使用)
140KB
3.5K SLoC
COITrees: 缓存无关区间树
COITrees实现了一个数据结构,用于对静态整数区间集合进行快速重叠查询,主要考虑基因组区间。
借鉴cgranges,此数据结构在连续内存中存储区间,但通过将节点存储在顺序的van Emde Boas布局中提高了查询性能。计算布局需要一些额外的时间和内存,但提高了查询树的平均缓存局部性。如果区间集合相对较大,并且执行了足够多的查询,则通常会优于其他数据结构。
SortedQuerent类型实现了另一种查询策略,该策略跟踪先前查询的结果。当一个查询与先前查询重叠时,可以重用该先前查询的结果,从而显著加速当前查询。(在基准测试中,这是--sorted选项。)
某些操作可以通过使用SIMD指令进一步加速。已实现了两种COITree变体,以利用x86-64 cpu上的AVX2指令(AVXCOITree)和ARM cpu上的Neon指令(NeonCOITree)。如果检测到适当的指令集,则将COITree类型定义为这些类型之一。通常需要使用环境变量RUSTFLAGS="-Ctarget-cpu=native"进行编译才能实现此功能。后备实现(BasicCOITree)支持Rust编译到任何平台,并且仍然非常高效。
尝试使用
这是一个主要用于其他程序中的库,但出于基准测试的目的,它包括一个用于交集 BED 文件的程序。
要尝试使用,只需克隆此存储库并运行
cargo run --release --example bed-intersect -- test1.bed test2.bed > intersections.bed
基准测试
A 是 Ensembl 人类基因组注释中的 2,755,864 个区间,B 是来自某些 RNA-Seq 对齐的 62,159,484 个区间,而 B' 是 B 的前 200 万行。
按顺序排序的区间
| A 与 B | B 与 A | A 与 A | B' 与 B' | |
|---|---|---|---|---|
| coitrees AVX | 11.8 秒 | 3.7 秒 | 0.7 | 5.3 秒 |
coitrees AVX (--sorted) |
6.4 秒 | 4.2 秒 | 0.6 秒 | 0.5 秒 |
| coitrees | 11.4 秒 | 5.2 秒 | 0.8 秒 | 8.3 秒 |
coitrees (--sorted) |
5.8 秒 | 5.4 秒 | 0.6 秒 | 0.5 秒 |
cgranges (bedcov-cr -c) |
35.4 秒 | 6.6 秒 | 2.0 秒 | 17.6 秒 |
| AIList | 13.8 秒 | 10.1 秒 | 1.1 秒 | 18.4 秒 |
| CITree | 20.1 秒 | 13.5 秒 | 1.6 秒 | 45.7 秒 |
| NCList | 22.5 秒 | 16.8 秒 | 1.9 秒 | 39.8 秒 |
| AITree | 23.8 秒 | 26.3 秒 | 2.1 秒 | 63.4 秒 |
bedtools coverage-计数-排序 |
257.5 秒 | 295.6 秒 | 71.6 秒 | 2130.9 秒 |
bedtools coverage-计数 |
322.4 秒 | 378.5 秒 | 75.0 秒 | 3595.9 秒 |
带有覆盖率
| A 与 B | B 与 A | A 与 A | B' 与 B' | |
|---|---|---|---|---|
| coitrees AVX | 18.2 秒 | 4.8 秒 | 1.1 秒 | 16.0 秒 |
| coitrees | 14.6 秒 | 5.7 秒 | 1.0 秒 | 12.0 秒 |
| cgranges | 38.4 秒 | 8.1 秒 | 2.2 秒 | 31.0 秒 |
| CITree | 23.2 秒 | 25.6 秒 | 2.0 秒 | 160.4 秒 |
随机顺序的区间
| A 与 B | B 与 A | A 与 A | B' 与 B' | |
|---|---|---|---|---|
| coitrees AVX | 23.9 秒 | 7.2 秒 | 1.6 秒 | 6.1 秒 |
| coitrees | 24.2 秒 | 8.9 秒 | 1.9 秒 | 9.4 秒 |
cgranges (bedcov-cr -c) |
55.7 秒 | 11.1 秒 | 3.3 秒 | 19.6 秒 |
| AIList | 31.2 秒 | 18.2 秒 | 2.3 秒 | 19.3 秒 |
| CITree | 39.4 秒 | 19.0 秒 | 2.9 秒 | 47.1 秒 |
| NCList | 42.7 秒 | 23.8 秒 | 3.4 秒 | 44.0 秒 |
| AITree | 225.3 秒 | 134.8 秒 | 14.7 秒 | 921.6 秒 |
bedtools coverage-计数 |
1160.4 秒 | 849.6 秒 | 104.5 秒 | 9254.6 秒 |
带有覆盖率
| A 与 B | B 与 A | A 与 A | B' 与 B' | |
|---|---|---|---|---|
| coitrees AVX | 34.3 秒 | 8.8 秒 | 2.2 秒 | 16.3 秒 |
| coitrees | 29.6 秒 | 9.7 秒 | 2.3 秒 | 13.1 秒 |
| cgranges | 57.6 秒 | 12.5 秒 | 3.6 秒 | 32.6 秒 |
| CITree | 50.0 秒 | 32.5 秒 | 3.8 秒 | 170.4 秒 |
所有基准测试均在 ryzen 5950x 上运行。
讨论
这些基准测试在某种程度上是现实的,因为它们使用真实数据,但它们并不完全是苹果对苹果的,因为它们都涉及解析和写入 BED 文件。大多数程序(包括 coitrees 中实现的程序)都有不完整的 BED 解析器,有些使用其他快捷方式,如假设一组具有特定命名方案的固定染色体。
bedtools 的缺点是它实际上是一个有用的工具,而不仅仅是为了赢得基准测试而实现。很明显,它可以快得多,但毫无疑问,一些成本可以归因于功能丰富性、完整性和安全性。
如果您怀疑有更快的 BED 交集程序(或者只是有趣),请告诉我,我会尝试对其进行基准测试。