2011-08-19 106 views
5

性能方面,多次直接访问数组元素还是将其值赋给变量并使用该变量会更好?假设我将在下面的代码中多次引用该值。直接访问数组元素与将其分配给变量

这个问题背后的原因是,访问一个数组元素大概会在每次完成时涉及一些计算成本,而不需要额外的空间。另一方面,将该值存储在变量中会消除这种访问成本,但会占用额外的空间。

// use a variable to store the value 
Temp = ArrayOfValues(0) 
If Temp > 100 Or Temp < 50 Then 
    Dim Blah = Temp 
    ... 

// reference the array element 'directly' 
If ArrayOfValues(0) > 100 Or ArrayOfValues(0) < 50 Then 
    Dim Blah = ArrayOfValues(0) 
    ... 

我知道这是一个简单的例子,但假设我们在谈论在实际使用中在什么点(其中值将被多次引用)规模较大的空间和计算时间价值之间的权衡考虑(如果有的话)?

+1

优化编译器将对HLL进行彻底的尝试。如果您使用汇编或关闭优化,寄存器比缓存更快,所以应尽可能将常用值加载到寄存器中。总的来说,我认为注册压力和内存层次之间的临界点可能是经验问题。 – Patrick87

回答

2

内存消耗的开销非常有限,因为对于引用类型,它只是一个指针(几个字节),大多数值类型也只需要几个字节。

在大多数语言中,数组是非常高效的结构。获得索引不涉及任何查找,只是一些数学(每个数组插槽需要4个字节,所以第11个插槽位于偏移量40)。然后,边界检查可能会有一些开销。为新的本地变量分配内存并释放它需要一些cpu周期。所以最终它还取决于通过复制到本地变量来消除多少个数组查找。

事实是,你真的需要非常糟糕的硬件或者真的有很大的循环,因为这非常重要,如果它对它进行了体面测试。我个人经常选择单独变量,因为我发现它使代码更易读。

你举的例子是奇数顺便说一句,因为你创建局部变量之前做2个阵列查找:) 这更有意义(排除2个查询)

Dim blah = ArrayOfValues(0) 
if blah > 100 or blah < 50 then 
... 
2

这是标记语言无关,但我不真的不相信它是。这篇文章回答了问题的C和C++版本。

优化编译器可以照顾“裸”数组访问;在C或C++中,如果没有函数被调用,没有理由认为编译器不记得内存位置的值。例如。

int a = myarray[19]; 
int b = myarray[19] * 5; 
int c = myarray[19]/2; 
int d = myarray[19] + 3; 

但是,如果myArray的不只是定义为int [],但实际上是一些“花哨”,特别是一些用户定义的容器类型与另一个转换单元中定义的函数operator[](),那么该功能必须是每次请求该值时都会调用该函数(因为该函数正在返回内存中的位置处的数据,并且本地函数不知道该函数的结果是否意图保持不变)。尽管如此,即使使用'裸'数组,但如果在函数调用周围多次访问同一个东西,编译器也必须假设该值已被更改(即使它可以记住地址本身)。例如。

int a = myarray[19]; 
NiftyFunction(); 
int b = myarray[19] * 8; 

编译器无法知道myarray [19]在函数调用之前和之后将具有相同的值。因此,一般来说,如果您知道某个值在本地范围内是不变的,请将其“缓存”到局部变量中。您可以防守编程和使用断言来验证这种情况下,你已经把对事物:

int a = myarray[19]; 
NiftyFunction(); 
assert(myarray[19] == a); 
int b = a * 8; 

最后一个好处是,它更容易在调试器来检查的值,如果他们不阵列中的某处埋藏。

+1

+1“这是标记的语言不可知论者,但我并不真的相信它。” C#答案在某些方面可能会有所不同,但我没有资格提供它。 – ClickRick

相关问题