【问题标题】:Does the dot operator cost anything in terms of operations? [duplicate]点运算符在操作方面是否有任何成本? [复制]
【发布时间】:2015-10-14 14:59:15
【问题描述】:

我有一个类似的循环

for (int i = 2; i <= ViewBag.numPages; ++i)

我想知道如果我这样写会不会更快

for (int i = 2, n = ViewBag.numPages; i <= n; ++i)

如果可能,请给我一个深入(低级)的解释

【问题讨论】:

  • 如果是这样,编译器无论如何都会优化它,除非你把它关掉。即使这样,成本也可能非常小,就像两条机器指令一样。
  • 另外:推荐阅读:codeproject.com/Articles/844781/…
  • 你对“非常”的定义很奇怪。首先,重新命中相同的地址将被缓存。其次,在您的循环计数开始担心 int32 溢出之前,ram 访问成本不会很高。
  • 顺便说一句。你不是 Donald Knuth.. 你误用了这个名字并问了一个真人肯定知道的简单问题!

标签: c# asp.net optimization


【解决方案1】:

假设ViewBag.numPages 在您的循环期间保持不变,我倾向于第二种变体,即:

for (int i = 2, n = ViewBag.numPages; i <= n; ++i)

为什么?

  • 也许你的第一个 numPages 是一个简单的字段,但如果它是一个重要的属性,你的循环必须在每次迭代之前评估它(调用它的 getter),这肯定比评估它一次然后缓存更昂贵结果。

  • 编译器优化是编译器的一个实现细节,你不知道编译器究竟做了什么来提高性能。

    手动缓存 ViewBag.numPages 意味着您不必依赖编译器可能会或可能不会为您做的优化。

话虽如此,如果ViewBag.numPages 是一个(常量)字段,而不是一个属性,那么这两个代码变体的执行速度可能非常接近(在最好的情况下,我们讨论的是访问 CPU 之间的区别注册与以原子方式访问可能位于 CPU 内存缓存中的一个内存位置),差异根本不重要。

【讨论】:

    【解决方案2】:

    点运算符在操作方面有什么成本吗?

    这取决于。对于您的 ASP.NET 代码:

    for (int i = 2; i <= ViewBag.numPages; ++i)
    

    ...那么上述内容可能会受到优化(或者可能是 CPU 缓存),因此您尝试优化的任何操作都可能不会引起注意。

    COM

    但是,您的问题 title 没有提到 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)
    

    【讨论】:

    • CPU 如何在不断言没有其他线程在循环期间更改ViewBag.numPages 的情况下缓存该值?
    • Asp.net 它在标签中..
    • @BasvanStein 同意。我不相信这个问题与 ASP.NET 有很大的关系。 :)
    • @Rotem Simple - 您几乎无法保证多线程中数据的陈旧性。这是使多线程相当困难的事情之一。 CPU 将跟踪内存位置的变化并在必要时刷新相关的缓存行,就像使用单线程代码一样 - 但是,它不会立即发生。
    猜你喜欢
    • 1970-01-01
    • 2011-11-21
    • 2011-02-25
    • 1970-01-01
    • 2012-09-27
    • 2014-12-01
    • 1970-01-01
    • 2023-03-24
    • 2011-09-01
    相关资源
    最近更新 更多