c# - out 和 ref 可以用作临时变量吗?

标签 c# .net

当我们在计算中使用 outref 时,有多个赋值并从中读取,它有什么缺点?会影响性能吗?

static bool TrySomeFunction(int x, int y, out int result)
{
    result = 8;
    for (int i = 0; i < x; i++)
    {
        result += result + x;
        if (result == y)
            return false;
    }
    return true;
}

或者我们应该更好地使用附加变量:

static bool TrySomeFunction(int x, int y, out int result)
    {
        int temp = 8;
        for (int i = 0; i < x; i++)
        {
            temp += temp + x;
            if (temp == y)
            {
                result = 0;
                return false;
            }      
        }
        result = temp;
        return true;
    }

更新:将函数名称从 SomeFunction 更改为更明确的用途。

最佳答案

事实证明,我们做的计算越多,两者的性能差异就越大。

我相信这是意料之中的,因为在这里我们看到了额外的间接级别。 ldindstind用于获取/设置 out 参数(间接)和 ldoc 值的操作与 stloc用于获取/设置局部变量的值。

我认为编译器在这里无法进行任何优化(至少将 UseOutExtensively 转换为 DontUseOutExtensively),因为如果其他线程可能会改变方法的行为在函数执行的同时写入 out 参数的位置。

测试

让我稍微简化一下您的功能,以便我们只专注于我们感兴趣的内容:

void UseOutExtensively(out int result)
{
    result = 0;
    for (int i = 0; i < 100; i++)
    {
        int temp = result;
        result = temp;
    }
}

void DontUseOutExtensively(out int result)
{
    int temp = 8;
    for (int i = 0; i < 100; i++)
    {
        int anotherTemp = temp;
        temp = anotherTemp;
    }
    result = temp;
}

所以函数没有做任何有用的事情,它们只是在变量之间交换相同的值。因此我们没有复杂的添加和条件,只获取/设置一个 out 变量和获取/设置一个局部变量。

所以测试程序如下:

int Iterations = 10000000; // we'll try 10^7, 10^8 && 10^9

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
  UseOutExtensively(out int result);

Console.WriteLine("Using out extensively: {0}",
                          sw.ElapsedMilliseconds);

sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
  DontUseOutExtensively(out int result);

Console.WriteLine("Don't use out extensively: {0}",
                          sw.ElapsedMilliseconds);

结果:

<头>
迭代 UseOutExtensively DontUseOutExtensively
10^7 918 330
10^8 8850 3331
10^9 92009 34823

我们看到我们执行的操作越多,性能差异就越明显。

关于c# - out 和 ref 可以用作临时变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71356352/

相关文章:

c# - 类返回的默认值

c# - 有时可以获取文本但有时显示 "Unable to find element with selector"

c# - 如何首先使用 EF 4 代码重构代码/数据库模式 - 数据迁移

c# - 备用 UniqueId 生成技术

c# - 如何散列文件的前 N ​​个字节?

c# - 获取有关 Azure 部署的更详细的错误详细信息

c# - 如何使用即席 sql 查询 : SQL Filtering 进行延迟加载

c# - 显示和隐藏 winforms 的部分内容(扩展?)C# .NET

c# - 如何使用 PrincipalContext 连接到本地主机?

c# - 将 aspx 转换为 pdf