对于ELKI,我需要(并且拥有)比标准 Java JDK 和 Collections API 提供的更灵活的排序实现。(排序不是我的最终目标。我使用部分排序来批量加载索引结构,例如 kd-tree 和 R*-tree,并且我想为这些提供一个相当通用的实现,比目前 ELKI 中的更通用- 但无论哪种方式,优化排序都意味着优化索引构建时间)。
但是,排序算法的缩放比例会因您的数据大小而异。对于微小的数组,插入排序可以很好地执行是一个众所周知的事实(事实上,大多数快速排序实现将回退到低于某个阈值的插入排序);不是通过理论,而是通过排序理论未考虑的 CPU 流水线和代码大小影响。
所以我目前正在对一些排序实现进行基准测试,以找到满足我特定需求的最佳组合;我希望我更灵活的实现在某种程度上与 JDK 默认实现(已经微调,但可能适用于不同的 JDK 版本)相提并论。
从长远来看,我需要这些东西易于重现和重新运行。在某个时候,我们会看到 JDK8。在 Dalvik VM 上,结果也可能与 Java 7 不同。哎呀,它们甚至在 AMD、Core i7 和 Atom CPU 上也可能不同。所以也许 Cervidae 会包含不同的排序策略,并在类加载时间上选择最合适的一种。
我目前的工作在 GitHub 上:https ://github.com/kno10/cervidae
所以现在到实际的问题。最新的 caliper 提交为宏基准添加了一些实验性代码。但是,我面临的问题是我需要两者。当运行时间小于定时器分辨率的 0.1% 时,Caliper 宏基准测试失败;对于 10000 个对象,一些算法达到了这个阈值。与此同时,微基准测试抱怨说,当你的运行时间太长时,你应该做一个宏基准测试……
因此,为了对不同的排序大小进行基准测试,我实际上需要一种根据运行时动态地从微基准测试切换到宏基准测试的方法。事实上,我什至更喜欢 caliper 自动意识到运行时对于宏基准测试来说足够大,然后只进行一次迭代。
现在,我正在尝试通过使用以下方法来模拟它:
@Macrobenchmark
public int macroBenchmark() { ... }
public int timeMicroBenchmark(int reps) {
int ret = 0;
for (int i = 0; i < reps; i++) {
ret += macroBenchmark();
}
}
在两种情况下共享基准测试代码。另一种代码是使用
@Macrobenchmark
public int macroBenchmark() {
return timeMicroBenchmark(1);
}
public int timeMicroBenchmark(int reps) { ... }
两个“适配器”中哪一个更可取?从微观一直到宏观获得一致基准测试的任何其他提示?
鉴于 caliper WebUI 目前无法使用,您使用什么来分析结果?我目前正在使用一个小型 python 脚本来处理 JSON 结果并报告加权平均值。事实上,我更喜欢旧的文本报告而不是 Web UI。
哦,当热点编译发生在基准测试循环中时,有没有办法让 Caliper 重新运行基准测试?现在它记录了一个错误,但也许它可以重新启动基准测试的那部分?