我目前正在学习C#中的运算符和表达式,我明白如果我想将变量的值增加5,我可以通过两种不同的方式来实现:a = a + 5
和{{1} }。显然,第二种方式更容易,写得更快,阅读更愉快。但是,在计算机方面,a += 5
比a += 5
快?编译和执行的时间是否比表达式的较长版本少?
答案 0 :(得分:14)
然而,在计算机方面,比a = a + 5?
快+ = 5
两者都相同,第一个(a += 5
)等于第二个a = a + 5
。
你可能会看到:
使用
+=
赋值运算符的表达式,例如x += y
等同于x = x + y
,但x仅评估一次。 +运算符的含义取决于x和y的类型 (数字操作数的加法,字符串操作数的连接,和 等等。)
因此它取决于a
的类型,并且在多个线程访问变量a
的情况下,您可能会得到不同的结果。但对于大多数其他情况,它将是相同的:
代码:
static void Main(string[] args)
{
int a = 10;
a += 5;
Console.WriteLine(a);
}
在发布模式下构建IL
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 14 (0xe)
.maxstack 2
.locals init ([0] int32 a)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.5
IL_0005: add
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call void [mscorlib]System.Console::WriteLine(int32)
IL_000d: ret
} // end of method Program::Main
通过代码生成相同的IL:
static void Main(string[] args)
{
int a = 10;
a = a + 5;
Console.WriteLine(a);
}
IL(同样)是:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 14 (0xe)
.maxstack 2
.locals init ([0] int32 a)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.5
IL_0005: add
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call void [mscorlib]System.Console::WriteLine(int32)
IL_000d: ret
} // end of method Program::Main
答案 1 :(得分:6)
这取决于a
是什么。 a = a + 5
评估a
两次。 a += 5
只需一次 评估a
。
如果a
是一个整数,那么大多数情况下这种差异可能并不重要,尽管严格来说不是所有情况。例如,如果从多个线程访问a
,那么竞争条件的确切类型和窗口可能会有所不同。
最重要的是,如果评估表达会导致副作用,那么观察到的一次副作用与观察两次的副作用之间的差异。在某些情况下,这可能是一个大交易,可能影响代码的正确性,而不仅仅是它的速度。