If 语句中的内存效率



我更多地考虑我的程序现在将使用多少系统内存。我目前正在大学学习A级计算,我知道在大多数程序中,差异可以忽略不计,但我想知道以下是否真的有任何差异,在任何语言中。

假设我想输出"真"或"假",具体取决于条件是否为真。就个人而言,我更喜欢做这样的事情:

Dim result As String
If condition Then
   Result = "True"
Else
   Result = "False"
EndIf
Console.WriteLine(result)

但是,我想知道以下内容是否会消耗更少的内存等:

If condition Then
   Console.WriteLine("True")
Else
   Console.WriteLine("False")
EndIf

显然,这是一个非常简化的例子,在我的大多数情况下,还有更多的东西要输出,我意识到在大多数商业程序中,这种陈述很少见,但希望你明白这个原则。

我在这里专注于 VB.NET,因为这是课程中使用的语言,但实际上我很想知道这在不同的编程语言中有何不同。

使if快或慢的主要问题是可预测性。

现代CPU(2000年之后的任何CPU(使用一种称为分支预测的机制。
首先阅读上面的链接,然后继续阅读下面的链接...

哪个更快?
if语句构成一个分支,因为 CPU 需要决定是跟随还是跳过 if 部分。
如果它猜对了分支,则跳转将在 0 或 1 个周期内执行(在 1Ghz 计算机上为 1 纳秒(。
如果它没有正确猜测分支,跳跃将需要 50 个周期(给予或接受((微索的 1/200(。

因此,要像人类一样感受到这些差异,您需要执行 if 语句数百万次。

上面的两个语句可能会在完全相同的时间内执行,因为:

  1. 为变量赋值所需的时间可以忽略不计;在多标量 CPU* 上平均少于一个 CPU 周期。
  2. 调用具有常量参数的函数需要使用不可见的临时变量;因此在所有可能性中,代码 A 编译为与代码 B 几乎完全相同的目标代码。

*( 所有当前的 CPU 都是多标量的。

消耗更少的内存
如上所述,两个版本都需要将布尔值放入变量中。
版本 A 使用由您声明的显式版本;版本 B 使用编译器声明的隐式版本。

但是,版本 A 保证只有一次对函数 WriteLine 的调用。
虽然版本 B 可能(也可能没有(对函数WriteLine进行了两次调用。
如果编译器中的优化器良好,则代码 B 将转换为代码 A,如果不是,它将保留冗余调用。

废物
有多严重调用大约需要 10 个字节来分配字符串(Unicode 每个字符 2 个字节(。
但另一个版本也是如此,所以这是相同的。
这为调用留下了 5 个字节。再加上一些额外的字节来设置堆栈帧。
因此,假设由于您完全可怕的编码,您现在已经浪费了 10 个字节。

没什么好担心的。

从可维护性的角度来看
计算机代码是为人类而不是机器编写的。
因此,从这个角度来看,代码A显然是优越的。想象一下,不是在 2 个选项(真或假(之间进行选择,而是在 20 个选项之间进行选择。
只调用该函数一次。
如果您决定更改另一个函数的 WriteLine,您只需在一个地方更改它,而不是两个或 20 个。

如何加快速度?
有 2 个值几乎是不可能的,但如果你有 20 个值,你可以使用查找表。
显然,除非代码被多次执行,否则这种优化是不值得的。

如果您需要知道指令将占用的确切内存量,您可以在代码上使用ildasm,并亲自查看。但是,代码消耗的内存量在今天的重要性要小得多,因为内存如此便宜和丰富,并且编译器足够聪明,可以看到常见模式并减少它们生成的代码量。

一个更大的问题是代码的可读性:如果复杂的条件链总是导致打印有条件设置的结果,那么你的第一个代码块以比第二个更干净的方式表达这个想法。在其他条件相同的情况下,您应该更喜欢您认为最易读的任何形式的代码,并让编译器担心优化。

附言不言而喻,Console.WriteLine(condition)会产生相同的结果,但这当然不是你问题的重点。

最新更新