我有一个像
这样的循环for (int i = 2; i <= ViewBag.numPages; ++i)
我想知道如果我把它写成
会更快for (int i = 2, n = ViewBag.numPages; i <= n; ++i)
如果可能,请给我一个深层次(低级别)的解释
答案 0 :(得分:1)
点运算符在运算方面是否有任何成本?
这取决于。对于您的ASP.NET代码:
for (int i = 2; i <= ViewBag.numPages; ++i)
...然后上面的内容可能会受到优化(或者可能是CPU缓存),因此您在尝试优化时所做的任何事情都可能不明显。
但是,您的问题标题未提及ASP.NET(虽然后来标记为asp.net),因此想象一下ViewBag
实际上是 COM对象< /强>
for (int i = 2; i <= ViewBag.numPages; ++i)
...那将是非常昂贵的,不受.NET优化的影响我不会想到。调用COM,特别是通过IDispatch
调用COM比访问本地对象上的.NET属性要慢得多。
所以在COM的情况下你应该:
for (int i = 2, n = ViewBag.numPages; i <= n; ++i)
答案 1 :(得分:1)
假设ViewBag.numPages
在循环期间保持不变,我赞成第二种变体,即:
for (int i = 2, n = ViewBag.numPages; i <= n; ++i)
为什么?
也许你的第一个numPages
是一个简单的字段,但如果它是一个非平凡的属性,你的循环必须在每次迭代之前评估它(调用它的getter),这肯定比评估它更昂贵它一次然后缓存结果。
编译器优化是编译器的一个实现细节,你不知道编译器为了提高性能到底做了什么。
手动缓存ViewBag.numPages
意味着您不必依赖编译器可能会或可能不会为您执行的优化。
话虽如此,如果ViewBag.numPages
是一个(常量)字段,而不是属性,那么两个代码变体的执行速度可能都非常接近(在最好的情况下,我们正在谈论差异在访问CPU寄存器与原子地访问可能在CPU内存缓存中的一个内存位置之间,差异并不重要。