Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将变量赋给表达式是否更节省内存?_C#_.net - Fatal编程技术网

C# 将变量赋给表达式是否更节省内存?

C# 将变量赋给表达式是否更节省内存?,c#,.net,C#,.net,什么更有效率 decimal value1, value2, formula 这: 或者这个: for(int i = 0; i>1000000000000; i++) { value1 = getVal1fromSomeWhere(); value2 = getVal2fromSomeWhere(); formula = value1*value2 + value1/value2; SendResultToA(formul

什么更有效率

decimal value1, value2, formula
这:

或者这个:

for(int i = 0; i>1000000000000; i++)
{
        value1 = getVal1fromSomeWhere();
        value2 = getVal2fromSomeWhere();
        formula = value1*value2 + value1/value2;
        SendResultToA(formula);
        SendResultToA(formula);
}
直觉上我会选择后者

我想在每次迭代(
decimal
formula
)时都有一个额外的赋值,而在没有额外变量的情况下不断地执行计算,这两者之间有一个折衷

编辑:
嗯。上帝每次我问问题时都要经过这个过程吗?
如果我问它,那是因为它对我来说很重要,伙计们。 不是每个人都生活在一个温和的非记忆批判的世界里,醒醒吧! 这只是一个过于简单的例子。我正在做数以百万计的科学计算和云计算多线程的工作,不要把我当成傻瓜:-)

所以是的肯定每纳秒都很重要


<强> ps:我几乎后悔C++和指针。自动内存管理和GC肯定会让开发人员变得无知和懒惰:-P

除非你一秒钟要做数万次,否则这一点都不重要。优化可读性和可维护性

编辑:仇恨者会仇恨的,好吧,好了,给你。我的代码:

static void MethodA()
{
    for (int i = 0; i < 1000; i++) {
        var value1 = getVal1fromSomeWhere();
        var value2 = getVal2fromSomeWhere();
        SendResultToA(value1 * value2 + value1 / value2);
        SendResultToB(value1 * value2 + value1 / value2);
    }
}

static void MethodB()
{
    for (int i = 0; i < 1000; i++) {
        var value1 = getVal1fromSomeWhere();
        var value2 = getVal2fromSomeWhere();
        var formula = value1 * value2 + value1 / value2;
        SendResultToA(formula);
        SendResultToB(formula);
    }
}
static void MethodA()
{
对于(int i=0;i<1000;i++){
var value1=getval1fromwhere();
var value2=GetVal2Fromsomeone();
SendResultToA(value1*value2+value1/value2);
SendResultToB(value1*value2+value1/value2);
}
}
静态void方法b()
{
对于(int i=0;i<1000;i++){
var value1=getval1fromwhere();
var value2=GetVal2Fromsomeone();
var公式=value1*value2+value1/value2;
SendResultToA(配方奶粉);
SendResultToB(公式);
}
}
以及它们生成的实际x86程序集:

方法A:

方法B:

它们非常长,因为它内联了getVal[1/2]fromwhere和SendResultTo[A/B],我将其连接到Random和Console.WriteLine。我们可以看到,事实上,CLR和抖动都不够聪明,无法重复之前的计算,因此我们额外花费了318字节的x86字节代码来做额外的计算


然而,请记住这一点——即使是一个额外的页面错误或磁盘读/写,您通过这些优化获得的任何收益都会立即变得无关紧要。如今,CPU很少成为大多数应用程序的瓶颈——I/O和内存都是。针对空间局部性进行优化(即使用连续阵列以减少页面错误),并减少磁盘i/O和硬页面错误(即加载不需要的代码需要操作系统对其进行故障处理)

从某种程度上说,我认为你是对的。两者都具有同等的可读性(可以说)

请记住,循环迭代次数与本地内存需求无关。您只讨论了几个额外的字节(无论如何,该值将被放在堆栈上,以便传递到函数);然而,通过缓存计算结果而节省的周期*确实会随着迭代次数显著减少


*也就是说,前提是编译器不为您执行此操作。查看每种情况下生成的IL会很有启发性。

首先是概要文件,并且只有在必要时才进行这种微观优化。否则会优化可读性。在你的情况下,我认为第二个更容易阅读

你说的第二个代码有一个额外的赋值,无论如何都不是真的。公式的结果需要以两种代码存储到寄存器中。
编译代码后,额外变量的概念无效。例如,在您的例子中,编译器可以将
公式
存储在以前存储
value1
value2
的寄存器中,因为它们的生存期不重叠

如果第一个优化到第二个,我不会感到惊讶。我认为这种优化被称为“公共子表达式折叠”。但当然,只有在表达没有副作用的情况下才有可能

而且检查IL并不总是足以看到什么得到了优化。抖动也得到了优化。我有一些代码在IL中非常难看和缓慢,但在最终生成的x86代码中非常简短。当检查机器代码时,你需要确保它实际上是优化的。例如,如果您在VS中运行,即使发布代码没有完全优化


因此,我的猜测是,如果编译器能够优化它们,那么它们的速度同样快,另外,第二个更快,因为它不需要对公式求值两次。

您必须反汇编字节码和/或基准来确定,但我认为这可能是相同的,因为编译器很容易看到
公式(在循环范围内)不会改变,可以很容易地直接“内联”(替换)


编辑:由于用户代码注释正确,分解字节码可能不够,因为优化可能只是在jitting之后才引入。

OP没有询问哪种做法更好,但哪种更有效。是的,过早优化,诸如此类。我们明白了。这是否意味着我们不能讨论实际效率?是的,这只是一个例子,我所做的操作有点复杂和重复,在许多线程上,所以这对我来说很重要。+1表示硬数据。我不是一个憎恨者,只是厌倦了这些轻率的回答,它们不是答案。@harpo:不,事实上,你不能对实际效率进行有意义的讨论。获得实际效率的方法是在谨慎控制的条件下衡量绩效,正如Paul所做的那样。没有数据的扶手椅上的讨论毫无意义;这是在事实之前的理论,而不是从知识的立场。ra无法实现效率
static void MethodA()
{
    for (int i = 0; i < 1000; i++) {
        var value1 = getVal1fromSomeWhere();
        var value2 = getVal2fromSomeWhere();
        SendResultToA(value1 * value2 + value1 / value2);
        SendResultToB(value1 * value2 + value1 / value2);
    }
}

static void MethodB()
{
    for (int i = 0; i < 1000; i++) {
        var value1 = getVal1fromSomeWhere();
        var value2 = getVal2fromSomeWhere();
        var formula = value1 * value2 + value1 / value2;
        SendResultToA(formula);
        SendResultToB(formula);
    }
}