问题标签 [microbenchmark]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
180 浏览

java - google caliper 尝试将基准测试结果上传到 microbenchmarks.appspot.com 时出现多个 500 错误

尝试为正在运行的基准测试上传 JSON 结果文件时,我看到了多个HTTP 500错误。Caliper日志中充满了与以下类似的异常:

但是,我的帐户下的页面上确实显示了一份报告/runs,因此它似乎至少可以上传其中的一些。对指定的 URL执行curl POST任何失败的试验都会导致相同的错误。

有没有其他人遇到过这些错误?我的配置中是否缺少某些内容?

卡尺config.properties

卡尺版本:

系统属性:

此外,错误日志建议手动上传失败的结果。但是,我在Microbenchmarks Appspot 页面上看不到任何上传结果的选项。

编辑 1:基准启动命令:

0 投票
1 回答
188 浏览

c - 缓存命中、未命中和预测 - 对性能的影响

我编写了以下玩具基准。

基本上,它以不同的步幅遍历数组。然后我绘制了结果:

在此处输入图像描述

(结果被平滑)

当 stride 为 ~128 时,CPU 可以将所有要访问的数据放入 L1 Cache 中。鉴于访问的线性,未来的读取可能是可以预测的。

我的问题是,为什么在那之后平均阅读时间不断增加?我对 stride=~128 的推理也适用于大于该值的值。

谢谢!

0 投票
3 回答
568 浏览

r - 为什么是“测量的负执行时间!” 出现错误?(以及如何处理它?)

我开始了解这个microbenchmark R包的一些功能。我从 Hadley Wickham 的这个出版物中实现了一个示例代码,并收到一个错误,我找不到任何准确的信息,我无法处理。提前感谢您的任何解释/提示等。

示例代码:

控制台输出:

更新。这是我的seesionInfo()控制台输出:

更新 2.包的作者要求我提供一些进一步的信息:

  • R 变量R.version

    R.version _
    platform x86_64-w64-mingw32
    arch x86_64
    os mingw32
    system x86_64, mingw32
    status
    major 3
    minor 0.2
    year 2013
    month 09
    day 25
    svn rev 63987
    language R
    version.string R version 3.0.2 (2013-09-25) 昵称飞盘帆船

  • 我电脑中 CPU 的品牌、型号和速度:

处理器:Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.70 GHz

内存:16,0 GB

系统类型:64位

更新 3。

我注意到上面代码的修改之一确实返回了正确的结果:

0 投票
5 回答
5038 浏览

java - 在构造函数中设置 Java 集合的大小是否更好?

如果我知道当时的大小,将大小传递Collection给构造函数会更好吗?在扩展和分配/重新分配Collection方面的节省效果是否显着?Collection

如果我知道的最小尺寸Collection但不知道上限怎么办。至少以最小的尺寸创建它仍然值得吗?

0 投票
2 回答
512 浏览

java - 如何在没有 maven 的情况下使用 Caliper 基准测试版快照?

我被要求使用 Google 的 Caliper 项目来创建一些微基准测试。我非常想使用最新的 beta 快照的注释功能,但是除了一些小例子之外,我很难找到关于如何实际运行这个东西的好文档……有一个视频教程可以指导用户新的 Maven 集成功能,我也被要求不要使用。

现在我只是从他们的一个中剥离了一个小例子,并用我从另一个 SO 问题中收集到的一些其他信息进行了修改:

运行它会告诉我我没有设置大小的默认值。我无法追踪我应该把它放在哪里。

通过注释掉 @Param 行并为 setUp 中的数组声明赋予硬值来完全删除“大小”只会导致它决定“没有要进行的实验”,我想这是有道理的。

如果有任何最新的资源或教程可以指出我做错了什么(可能很多,老实说)我会非常感激。

编辑:

根据一些建议,我已对此进行了更新:

我正在运行 beta 快照并将 Benchmarks 类作为参数传递。我收到以下信息:

它似乎没有检测到任何仪器。我没有传入任何内容,因为它在文档中提到它只是使用默认分配、运行时(这对我的目的来说很好)。

双重编辑:发现了那个问题,愚蠢的错误。一旦我确认它会做一个快速的记录。

0 投票
1 回答
663 浏览

java - 分支预测不起作用吗?

关于这个问题,答案指定未排序的数组需要更多时间,因为它未能通过分支预测测试。但是如果我们在程序中做一个小的改动:

在这里我已经替换(来自原始问题)

未排序的数组给出了大约。同样的结果,我想问为什么分支预测在这种情况下不起作用?

0 投票
1 回答
345 浏览

java - 什么可以解释编写对堆位置的引用的巨大性能损失?

在研究分代垃圾收集器对应用程序性能的微妙影响时,我发现在一个非常基本的操作(简单写入堆位置)的性能方面存在相当惊人的差异,即写入的值是原始值还是引用。

微基准

结果

由于整个循环几乎慢了 8 倍,因此写入本身可能慢了 10 倍以上。什么可以解释这种放缓?

写出原始数组的速度超过每纳秒 10 次写入。也许我应该问我问题的另一面:是什么让原始写作如此之快?(顺便说一句,我已经检查过了,时间与数组大小成线性关系。)

请注意,这都是单线程的;指定@Threads(2)将增加两个测量值,但比率将相似。


一点背景知识:卡表和相关的写屏障

年轻代中的对象可能碰巧只能从老年代中的对象访问。为了避免收集活动对象,YG 收集器必须知道自上次 YG 收集以来写入老年代区域的任何引用。这是通过一种称为卡表的“脏标志表”来实现的,它为每个 512 字节的堆块有一个标志。

当我们意识到每次写入引用都必须伴随着卡表不变的代码时,该方案的“丑陋”部分就出现了:必须标记卡表中保护被写入地址的位置一样。这段代码被称为写屏障

在特定的机器代码中,如下所示:

当写入的值是原始值时,这就是相同的高级操作所需要的全部内容:

写入屏障似乎“仅”贡献了一次写入,但我的测量表明它会导致数量级的减速。我无法解释这一点。

UseCondCardMark只会让事情变得更糟

如果条目已被标记为脏,则有一个非常模糊的 JVM 标志应该避免卡表写入。这主要在一些退化的情况下很重要,因为大量的卡表写入导致线程之间通过 CPU 缓存进行错误共享。无论如何,我尝试使用该标志:

0 投票
1 回答
471 浏览

java - 为什么 volatile 比 non-volatile 工作得更快?

阅读问题后为什么处理排序数组比处理未排序数组更快? 我们曾尝试将变量设置为 volatile(我预计,当我使用 volatile 时,它​​的工作速度肯定会变慢,但它的工作速度会更快)这是我没有 volatile 的代码:(它的工作时间约为 11 秒。)

输出是:



这是当我使用 arraySize 和数据变量作为 volatile 时,它​​的工作时间约为 7 秒:

volatile 的输出是:

我所期望的只是用 volatile 减慢这个过程,但它的工作速度更快。发生了什么事?

0 投票
1 回答
355 浏览

java - Java String = "" vs. new String("") 性能变化

我做了和这篇文章一样的测试: new String() vs literal string performance

这意味着我想测试哪个性能更好。正如我所料,结果是文字赋值更快。我不知道为什么,但是我用更多的赋值进行了测试,我注意到一些奇怪的事情:当我让程序执行超过 10.000 次的循环时,文字赋值相对而言并不比少于 10.000 的赋值快得多. 在 1.000.000 次重复时,它甚至比创建新对象还要慢。

这是我的代码:

我让它像上面写的那样运行。我刚刚学习 Java,我的老板让我做测试,在我展示测试结果后,他让我找到答案,为什么会发生这种情况。我在谷歌或stackoverflow上找不到任何东西,所以我希望有人能在这里帮助我。

谢谢!

0 投票
3 回答
1354 浏览

java - 为什么边界检查没有被消除?

我编写了一个简单的基准测试,以确定在通过按位与计算数组时是否可以消除边界检查。这基本上是几乎所有哈希表所做的:它们计算

作为 的索引table,其中或hhashCode派生值。结果表明边界检查没有被消除。

我的基准测试的想法非常简单:计算两个值ij,保证两者都是有效的数组索引。

  • i是循环计数器。当它被用作数组索引时,边界检查就被消除了。
  • j计算为x & (table.length - 1),其中x每次迭代都有一些值变化。当它被用作数组索引时,边界检查不会被消除。

相关部分如下:

另一个实验使用

反而。时间上的差异可能是 15%(在我尝试过的不同变体中非常一致)。我的问题:

  • 除了约束检查消除之外,还有其他可能的原因吗?
  • 是否有一些复杂的原因我看不出为什么没有约束检查消除j

答案摘要

MarkoTopolnik 的回答表明这一切都更加复杂,并且不能保证消除边界检查是胜利,尤其是在他的计算机上,“正常”代码比“屏蔽”代码慢。我想这是因为它允许进行一些额外的优化,这在这种情况下实际上是有害的(鉴于当前 CPU 的复杂性,编译器甚至几乎无法确定)。

leventov 的回答清楚地表明,数组边界检查是在“屏蔽”中完成的,并且它的消除使代码与“正常”一样快。

Donal Fellows 指出了这样一个事实,即屏蔽不适用于零长度表,x & (0-1)x. 所以编译器能做的最好的事情就是用零长度检查代替边界检查。但恕我直言,这仍然值得,因为零长度检查可以轻松移出循环。

建议的优化

由于a[x & (a.length - 1)]当且仅当 等价抛出a.length == 0,编译器可以执行以下操作:

  • 对于每个数组访问,检查索引是否已通过按位与计算。
  • 如果是这样,请检查是否有任何一个操作数被计算为长度减一。
  • 如果是这样,请将边界检查替换为零长度检查。
  • 让现有的优化来处理它。

这样的优化应该非常简单且便宜,因为它只查看SSA图中的父节点。与许多复杂的优化不同,它永远不会有害,因为它只是用稍微简单的检查代替了一项检查;所以没有问题,即使它不能移出循环。

我会将其发布到热点开发邮件列表。

消息

约翰·罗斯提交了一份RFE,并且已经有一个“快速而肮脏”的补丁