Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
Arrays 阵列访问占用O(1)时间是否可以改进?_Arrays_Big O - Fatal编程技术网

Arrays 阵列访问占用O(1)时间是否可以改进?

Arrays 阵列访问占用O(1)时间是否可以改进?,arrays,big-o,Arrays,Big O,我一直在读一本分配给课堂的书,书中提到数组访问需要O(1)个时间。我意识到这是非常快的(可能尽可能快),但是如果有一个循环必须多次引用它,那么分配一个临时变量以在数组中查找值有什么好处吗?或者使用临时变量仍然是O(1)吗 我假设这个问题与语言无关。我也意识到,即使答案是肯定的,优势也很小,我只是好奇。你能比O(1)时间表现得更好的唯一方法就是一开始就不必做任何事情。那将是O(0)时间 或者少说几句:不。如果我明白了,你是在问 for (int i=0; i<len; i++) { i

我一直在读一本分配给课堂的书,书中提到数组访问需要O(1)个时间。我意识到这是非常快的(可能尽可能快),但是如果有一个循环必须多次引用它,那么分配一个临时变量以在数组中查找值有什么好处吗?或者使用临时变量仍然是O(1)吗


我假设这个问题与语言无关。我也意识到,即使答案是肯定的,优势也很小,我只是好奇。

你能比O(1)时间表现得更好的唯一方法就是一开始就不必做任何事情。那将是O(0)时间


或者少说几句:不。

如果我明白了,你是在问

for (int i=0; i<len; i++) {
   int temp = ar[i];
   foo += temp;
   bar -= temp;
}
for(inti=0;i注意O(1)并不意味着“瞬时”。它只是意味着“至多是某个常数”。这意味着1和101000都是O(1),即使其中的第二个大于宇宙中的原子数

如果多次重复访问同一数组元素,则每次访问都需要O(1)个时间。将该数组元素存储在局部变量中也会有O(1)个查找时间,但常数可能不同。选择一个选项可能比选择另一个选项更好,但您确实必须对程序进行分析才能确定

在实践中,这种微优化不太可能对程序时间产生可测量的影响,除非您正在运行的代码占程序运行时间的很大一部分。如果我发现这样一个例子,即这种更改会对任何实际代码产生显著影响,我会感到震惊

现代体系结构可能会加快这一变化,但不会太快。如果您多次访问同一数组元素,处理器可能会将该部分数组保留在缓存中,从而使查找速度非常快。此外,一个好的优化编译器可能已经将非本地副本代码转换为本地副本c给你的颂歌


希望这有帮助!

现代CPU硬件中已经内置了一些东西(例如缓存线)这样做与您描述的类似,但更好的方式是临时变量无法做到。甚至更好的是,不需要修改源代码。

不。数组访问不是由火花和爱构成的神奇的零足迹。可以看到从C中的数组索引确定地址的算法。可以看到的维度越多阵列上的ave访问速度越慢,这是额外的操作(主要是
mul
s和条件,从成本上讲)需要到达最终的1D内存地址。即使您的数组只有一个维度,您仍然必须计算基址上的偏移量,这是一个单一的
添加操作,因此为O(1)。

即使使用#2,一次内存读取和两次内存读取之间仍然存在差异(好的,不需要一级缓存)是的,这正是我的意思(代码)。我不确定这是否是1次操作,这本书叫O(1),所以我写了同样的东西。看起来答案是没有改进的,它以同样的方式保持在一个低的水平。@詹德沃克,啊,你说得对。我必须在回答中转换思路。把它删除。“更好的方法是临时变量做不到的。”--临时变量做不到的事情是什么?你通常不能依赖临时变量的存储位置。临时变量是在内存中创建的吗?在寄存器中?在优化的情况下?谢谢你,我写了O(1)因为这本书是这样写的,我犹豫是否要写一个操作,因为我不知道这是否正确。我知道它永远不会有显著的区别,我主要想知道它是否有任何区别。
for (int i=0; i<len; i++) {
   foo += ar[i];
   bar -= ar[i];
}