2

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

假设我想根据条件是否为真输出“True”或“False”。就个人而言,我更喜欢这样做:

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,因为这是课程使用的语言,但我真的很想知道这在不同的编程语言中有何不同。

4

2 回答 2

3

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

现代 CPU(2000 年以后的任何产品)使用一种称为分支预测的机制
首先阅读上面的链接,然后阅读下面的内容......

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

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

上述两条语句的执行时间可能完全相同,因为:

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

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

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

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

浪费有多严重
调用大约需要 10 个字节来分配字符串(Unicode 2 个字节/字符)。
但是另一个版本也是如此,所以是一样的。
剩下 5 个字节用于调用。再加上一些额外的字节来设置堆栈帧。
因此,可以说由于您的编码非常糟糕,您现在浪费了 10 个字节。

没什么好担心的。

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

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

于 2013-10-06T13:40:14.067 回答
2

如果您需要知道指令将占用的确切内存量,您可以ildasm在您的代码上使用,并亲自查看。然而,今天你的代码消耗的内存量已经不那么重要了,因为内存非常便宜和丰富,编译器足够聪明,可以看到常见的模式并减少它们生成的代码量。

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

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

于 2013-10-06T12:57:58.783 回答