

C++中的数组寻址,是线性时间还是固定时间
source link: https://www.v2ex.com/t/868384
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

int datas[] = new int[m];
int v = *(datas + n);
在上述代码中,向系统申请了一段连续的内存,用于存放 m 个 int,然后需要访问第 n 个元素,那编译器 or 系统是如何处理(datas + n)这段代码的,
也就是说,当 m 和 n 都趋向于无穷大的时候(在系统的可接受范围内)
int v = *(datas + n);
这句代码执行的时间是固定的 O(1)时间,还是 O(n)?
另外,当 n 趋向于无穷大的时候,下列 2 句代码执行的时间差距有多大
int v1 = *(datas + 1);
int v2 = *(datas + n);
Inn0Vat10n 7 小时 19 分钟前 1 、O(1)
2 、不考虑编译器优化 /cache 等的话,没有差距 |
![]() |
ysc3839 7 小时 17 分钟前 via Android 只从编译后代码来看那应该是 O(1),因为编译出的代码中没有循环。但是具体运行耗时就得看平台了。
|
Jooooooooo 6 小时 52 分钟前 这涉及好几级的缓存...比如数据被虚拟内存置换到硬盘上了, 这读起来就算是 O(1) 的也会很慢. 但机械硬盘和 ssd 又不一样. 研究这种问题你得把假设讲明白.
|
![]() |
Saxton 6 小时 49 分钟前 连续的内存块地址也是连续的,在这片已知的连续内存块访问任意一个地址都是 O ( 1 ),因为都是已知的
|
yannxia 6 小时 37 分钟前 代码上是 O(1),具体的硬件上嘛,因为 L1/L2/L3/ 有限,就不一定是一模一样的了。
|
![]() |
Origami404 6 小时 34 分钟前 via Android 当 N 趋向无限大时,使用二进制编码索引的话,理论上应该是 O ( logN )的,因为最快的也就是二分去查找对应的单元格。
而平时认为的单次内存操作 O ( 1 )只不过是 **目前人类的计算机设计 /内存实现** 把对“由定长二进制地址找单元格”这个操作硬编码到硬件,从而对上层程序体现出来的特点罢了。外星人的电脑设计很可能就会直接底层支持任意长索引以至于它们的内存读写是 O ( logN )的。 所以要多学学纯函数式编程,万一外星人来侵略地球了还能给它们写写电脑病毒。(🐶,最近外星人入侵电影看多了) |
![]() |
cpstar 6 小时 30 分钟前 数组,不是链表结构,不需要挨个遍历。直接跳过去
差别就是 1 和 n 的计算难度,一个直接加一,另一个是挪几步缓存 add 之后再挪回去。 |
![]() |
Juszoe 6 小时 27 分钟前 不学计算机组成,编程处处是魔法 (🐶
|
haolongsun 4 小时 42 分钟前 重修 csapp 吧
|
dcsuibian 3 小时 17 分钟前 O(1)的。
数组寻址实际上就是数组的地址加上一个 n 号元素的偏移量( n*sizeof(int)),就得出了 n 号元素的地址。然后访问。 同时,RAM 里的 R 是 Random ,但不是“随机”而是“任意”,指的是:你给的任意一个地址,访问所花的代价都是一样的。(对比机械硬盘,访问盘中间的数据会快一点) 所以你访问数组第一个元素和访问第一万个元素的代价是一样的。 O(n)的话,那得是一个一个找过去的链表了。 |
![]() |
icyalala 3 小时 1 分钟前 单算法来说当然是 O(1)
但实际算下来有一堆可能性。比如那段内存之前访问过,刚好在 CPU Cache 里,那不同等级的 Cache 延迟不一样。如果触发了 page fault 那延迟更大。要是开启 NUMA ,那跨 NUMA 节点访问延迟也不一样。 |
![]() |
ipwx 3 小时 0 分钟前 不学计算机组成,编程处处是魔法 (🐶
|
dcsuibian 2 小时 57 分钟前 @Origami404 我觉得应该不是。
因为当地址到达后,每一位的信号都应该是并行发出的。没有必要等到第一位完全起作用了再弄第二位。 如果真是 O(logN)的话,那 64 位计算机花的时间就是 32 位计算机的 2 倍了。 |
![]() |
feather12315 2 小时 36 分钟前 via Android 就算触发 PF 、cache Miss ,它也是 O(1)
|
yanqiyu 1 小时 22 分钟前 如果你的程序被一台纸带机模拟(即存储器不能随机访问,那么就会是 O(n)),在带有随机存储器的机器上当然是 O(1)
|
johnkiller 51 分钟前 via iPhone 要取某项数据,只需要知道它的内存地址。
而得到数组某项的内存地址, 就是一次纯粹地址加法, 对于计算机而言, n+1 和 n+9999 ,在 cpu 运算上是没有任何区别。 所以结论肯定都是 O(1) |
![]() |
yehoshua 34 分钟前 via Android 《计算机组成原理》 《深入理解计算机系统》
|
![]() |
FYFX 9 分钟前 我其实挺好奇你怎么理解哈希表的访问时间的
|
Recommend
-
80
陈莉君老师门下研究生一枚,初次拥抱Linux,感受到了开源的魅力,支持开放、自由、分享,谢谢大家。 by 梁金荣
-
12
关注公众号 MageByte,设置星标点「在看」是我们创造好文的动力。后台回复 “加群” 进入技术交流群获更多技术成长。 数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中...
-
15
c 生成 ext2 文件(间接寻址) – 3 发表于 2018-05-11 16:05:00...
-
14
c 生成 ext2 文件(直接寻址) – 2 发表于 2018-05-11 16:05:00...
-
8
c 生成 ext2 文件(直接寻址) - 1 发表于 2018-05-11 15:05:00...
-
15
ext2 数据块寻址方式 发表于 2018-05-03 18:05:00...
-
12
本文首发于: https://blog.frytea.com/archives/544/ 当出现 PATH 下有一个与系统命令重名的命令时,先执行哪一个呢?当 PATH 下有多个重名命令...
-
5
[数据结构-线性表1.1] 数组(.NET源码学习) #Updated【2022.7.29 替换文中不清晰的代码图片】 数组,一种数据类型(在绝大数语言中不是基本数据类型)且为引用类型,在内存中以连续的内存单元...
-
8
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT中FlexSPI外设lookupTable里配置访问行列混合寻址Memory的参数值。 关于 FlexSPI 外设的 lo...
-
2
寄存器间接寻址寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。例如以下指令:LDR R0,[R1] /*R0←[R1]*/ STR R0,[R1] /*[R1]←R0*/...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK