- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Test1
以下始终比 Test2
快 10% ,尽管我总是用 0
调用该方法参数,所以 switch case 里面的东西——唯一的区别——永远不会被执行。
顺便说一句,将代码复制并粘贴到一个全新的项目中后,只需将测试函数的名称更改为 Main
,结果反过来。每次我运行那个项目时,Test2
是比较快的。
那么是什么因素导致这个速度越来越慢呢?
和:我可以故意影响 .net 中的性能以对我有利吗?
这些方法当然几乎什么都不做,因此对于主要涉及相同虚拟方法调用的测试而言,10% 的性能差异似乎很大.
注意这实际上是真实程序的最小版本,其中多个嵌套的 switch 语句会导致巨大的性能差异,不仅是 10%,而且是 100% 甚至更多,这显然是因为测试的嵌套 switch 分支内仅存在代码永远不要进入。 (所以也许这个最小版本省略了可能涉及的真实程序的一些其他方面,但它确实复制了显着且一致的性能差异)
编辑 在实际程序中,可能比这个问题中的现象更重要的是 switch 语句中的实际 case 语句是否适合通过 branch table 实现。与否 - (这取决于案例值中的差距 - 我可以通过查看生成的 IL 代码来验证这一点)
试运行
using System;
using System.Diagnostics;
class Test1 : ITest
{
public int Test(int a)
{
switch (a)
{
case 1: return a + a + a == 1234 ? 1 : 2;
case 2: return 2;
}
return 0;
}
}
class Test2 : ITest
{
public int Test(int a)
{
switch (a)
{
case 1: return 1;
case 2: return 2;
}
return 0;
}
}
class Program
{
static void Main(string[] args)
{
const long iterations = 200000000;
var test1 = new Test1();
var test2 = new Test2();
while (true)
{
var sw1 = Stopwatch.StartNew();
for (long i = 0; i < iterations; i++)
test1.Test(0);
sw1.Stop();
var sw2 = Stopwatch.StartNew();
for (long i = 0; i < iterations; i++)
test2.Test(0);
sw2.Stop();
var iterPerUsec1 = iterations / sw1.Elapsed.TotalMilliseconds / 1000;
var iterPerUsec2 = iterations / sw2.Elapsed.TotalMilliseconds / 1000;
Console.WriteLine("iterations per usec: " + (int) iterPerUsec1 + " / " + (int) iterPerUsec2 + " ratio: " + iterPerUsec1/iterPerUsec2);
}
}
}
interface ITest
{
int Test(int a);
}
iterations per usec: 369 / 342 ratio: 1.07656329512607
iterations per usec: 367 / 314 ratio: 1.16820632522335
iterations per usec: 372 / 337 ratio: 1.10255744679504
iterations per usec: 374 / 342 ratio: 1.09248387354978
iterations per usec: 367 / 329 ratio: 1.11451205881061
iterations per usec: 375 / 340 ratio: 1.10041698470293
iterations per usec: 373 / 314 ratio: 1.19033461920118
iterations per usec: 366 / 334 ratio: 1.09808424282708
iterations per usec: 372 / 314 ratio: 1.18497411681768
iterations per usec: 377 / 342 ratio: 1.10482425370152
iterations per usec: 380 / 346 ratio: 1.09794853154766
iterations per usec: 385 / 342 ratio: 1.12737583603649
iterations per usec: 376 / 327 ratio: 1.15024393718844
iterations per usec: 374 / 332 ratio: 1.12400483908544
iterations per usec: 383 / 341 ratio: 1.12106159857722
iterations per usec: 380 / 345 ratio: 1.10267634674555
iterations per usec: 375 / 344 ratio: 1.09211401775982
iterations per usec: 384 / 334 ratio: 1.14958454236246
iterations per usec: 368 / 321 ratio: 1.14575850263002
iterations per usec: 378 / 335 ratio: 1.12732301818235
iterations per usec: 380 / 338 ratio: 1.12375853123099
iterations per usec: 386 / 344 ratio: 1.12213818994067
iterations per usec: 385 / 336 ratio: 1.14346447712043
iterations per usec: 374 / 345 ratio: 1.08448615249764
...
最佳答案
基准测试是一门艺术,像这样可靠地测量非常快的代码是非常困难的。一般来说,15% 或更少的差异在统计上并不显着。我只能评论已发布代码中的缺陷,这是一个很常见的缺陷。典型的海森堡式的,影响结果的是测试本身。
第二个 for() 循环不如第一个 for() 循环优化。由优化器选择将哪些局部变量存储在 CPU 寄存器中引起的问题。特别是在 32 位程序中使用 long 时的一个问题,它会烧毁两个 CPU 寄存器。很有可能,提到无法重现它的评论者使用 x64 抖动进行了测试。
通过将测试移到单独的方法中,您可以减轻 CPU 寄存器分配器的压力:
static Stopwatch runTest1(Test1 test1, long iterations) {
var sw1 = Stopwatch.StartNew();
for (long i = 0; i < iterations; i++)
test1.Test(0);
sw1.Stop();
return sw1;
}
static Stopwatch runTest2(Test2 test2, long iterations) {
var sw2 = Stopwatch.StartNew();
for (long i = 0; i < iterations; i++)
test2.Test(0);
sw2.Stop();
return sw2;
}
static void Main(string[] args) {
const long iterations = 200000000;
var test1 = new Test1();
var test2 = new Test2();
while (true) {
var sw1 = runTest1(test1, iterations);
var sw2 = runTest2(test2, iterations);
// etc..
}
}
for (long i = 0; i < iterations; i++)
00000089 xor ebx,ebx
0000008b xor esi,esi
0000008d mov ecx,dword ptr [esp+4]
00000091 xor edx,edx
00000093 call dword ptr ds:[04732844h]
00000099 add ebx,1
0000009c adc esi,0
0000009f test esi,esi
000000a1 jg 000000AD
000000a3 jl 0000008D
000000a5 cmp ebx,0BEBC200h
000000ab jb 0000008D
for (long i = 0; i < iterations; i++)
000000f5 mov dword ptr [esp+2Ch],0
000000fd xor ebx,ebx
000000ff mov ecx,dword ptr [esp]
00000102 xor edx,edx
00000104 call dword ptr ds:[056E28B8h]
0000010a mov eax,ebx
0000010c mov edx,dword ptr [esp+2Ch] ; <== here
00000110 add eax,1
00000113 adc edx,0
00000116 mov dword ptr [esp+2Ch],edx ; <== here
0000011a mov ebx,eax
0000011c cmp dword ptr [esp+2Ch],0
00000121 jg 0000012D
00000123 jl 000000FF
00000125 cmp ebx,0BEBC200h
0000012b jb 000000FF
关于.net - 当唯一的区别在于未执行的代码路径时,为什么性能会有所不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31309289/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!