c# - 具有两个 Action 的一个循环 VS 具有一个 Action 的两个循环性能?

标签 c# performance loops

我对这个新手问题很感兴趣。

例如我们有两种情况:

  1. 我有一个带有两个函数的任意循环。 (WhileFor 无关紧要)。

    for (int i = 0; i < 1000; i++)
    {
        Function_1();
        Function_2();
    }
    
  2. 我有两个循环,每个循环有一个 Action 。

    for (int i = 0; i < 1000; i++)
    {
        Function_1();
    }
    
    for (int i = 0; i < 1000; i++)
    {
        Function_2();
    }
    

我知道 first 会工作得更快。

但这两种情况在执行速度上有什么区别呢? (百分比)

如果最大循环次数增加,性能会降低多少?

在这种情况下,什么(处理器或 RAM)承担更大的负载?

最佳答案

从纯理论的角度来看,两者之间没有区别。无论哪种方式,都是 O(N),到此为止。

从更实际的角度来看,缓存可以大大改变这个简单的答案。一个人可能比另一个人更有效地使用缓存。不过,这不一定是您展示的第一个。

在真实的(现代)计算机上,它基本上可以解决哪个问题可以更有效地使用缓存。

这又取决于 Function_1Function_2 使用了多少内存。如果 Function_1 和 Function_2 每个都涉及执行相当多的代码,那么它们每个都适合 L1 指令缓存,但它们加起来就不行,那么第二个版本可能会更快。在这种情况下,第一个版本(在两个函数之间交替)每次执行时都必须从主内存加载每个函数,因此您从主内存加载代码约 2000 次。对于第二个,您从内存中加载 Function_1 的代码一次,从缓存中执行 1000 次,然后对 Function_2 执行相同的操作。一共从主存加载 2 次。

在另一个方向,我们假设 Function_1 和 Function_2 的代码都可以放入指令缓存中,但是 Function_1 和 Function_2 对相同的数据进行操作,并且该数据的总量太大,无法放入数据缓存。

这通常会扭转这种情况:在一个数据 block 上执行 Function_1,然后在同一 block 数据上执行 Function_2 只会从内存中加载该数据一次,然后对其进行所有必要的计算,然后加载下一个 block 的数据等等。每个数据 block 仅从主内存加载一次。

在这种情况下,您的代码的第二个版本可能会慢大约 2 倍——它将加载一 block 内存并在其上执行 Function_1。然后它将加载第二个内存块,并在其上执行 Function_1,依此类推。使用 Function_1 处理完所有内存后,它将返回并加载所有相同的内存块以在其上执行 Function_2。

当然,在现代处理器中,也不是那么简单。我们现在经常有 2 或 3 级缓存,通常具有不同的逐出策略。第一级通常分为指令缓存和数据缓存,但您通常也至少有一个统一的级别。这并不能消除上述因素,但会使情况变得更加模糊。

有一个完整的研究领域,例如缓存感知和缓存无关算法,以帮助针对像您这样的情况做出明智的选择。缓存感知排序基于(更详细的版本)模型,如上,选择如何组织计算以适应缓存组织。缓存无视算法更倾向于相对通用的缓存模型,并提供良好的性能,几乎与特定缓存的组织方式无关。

关于c# - 具有两个 Action 的一个循环 VS 具有一个 Action 的两个循环性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58486228/

相关文章:

c# - Xamarin iOS CGPath 绘制带有弯角/圆角的多边形

c# - 动态 IFrame 调整大小在 IE 中不起作用?

windows - 批处理文件中的 For 循环错误地从文件读取输入 - 循环失败

javascript - 在 asp.net c# 中使用 JavaScript 过滤时保存 gridview 的状态

c# - 我如何使用简单的 C# WebClient 使用相同的键(到谷歌翻译)发布多个值

performance - Redis CPU 在排序集上的性能

sql-server - 使用游标的存储过程速度非常慢

python - 替代 time.sleep

loops - VBScript 创建一个多维数组并添加到其中?

java - 循环测试结果为空,程序崩溃