当我访问数组的元素时,在硬件级别会发生什么
What happens at a hardware level when I access an element of an array?
int arr [] = {69, 1, 12, 10, 20, 113};
当我这样做时会发生什么
int x = a[3];
????
我一直觉得a[3]
的意思是:
">从内存地址arr
开始。向前走 3 个内存地址。获取在该内存地址处表示的整数。
但是我对哈希表的工作原理感到困惑。因为如果哈希表被实现为一个"桶"数组(就像教授在本讲座中所说的那样:https://www.youtube.com/watch?v=UPo-M8bzRrc(,那么你仍然必须走到你需要的桶;因此,它们的访问效率并不比阵列高。
有人可以为我澄清这一点吗?
把记忆想象成一个大的两列表:
+---------+-------+
| ADDRESS | VALUE |
+---------+-------+
| ... | ... |
+---------+-------+
| 100 | 69 | <-- &arr[0] is 100
+---------+-------+
| 101 | 1 |
+---------+-------+
| 102 | 12 |
+---------+-------+
| 103 | 10 | <-- &arr[3] is 103
+---------+-------+
| 104 | 20 |
+---------+-------+
| 105 | 113 |
+---------+-------+
| ... | ... |
+---------+-------+
我想强调的是,这是一个高度简化的模型,但它应该让你了解正在发生的事情。您的计算机知道您的阵列从地址 100 开始。而且,由于给定数组中的所有元素大小相同,因此您可以通过在起始地址中添加 +3 来轻松访问数组的第三个元素。计算机不需要"行走"到数组的第三个元素,它只需抓取存储在内存中地址 100 + 3 的值。
如果要查看此操作的示例,请编译并运行以下代码:
#include <iostream>
using namespace std;
int main() {
int a[] = { 1, 2, 3 };
cout << "Address of a:tt" << &a[0] << endl;
cout << "Address of a[2]:t" << &a[2] << endl;
return 0;
}
记下 a 的地址。假设您的计算机使用的是 32 位整数,您应该看到 a[2] 的地址只是 a + 2*4 的地址。它添加 2*4 而不仅仅是 2 的原因是因为每个整数实际上使用 4 个字节的内存(即单个值将跨越 4 个地址(。
int x = a[3];
硬件确实(地址为a(+(3*sizeof(int((
这是一个标准的索引操作,通常可以使用专用硬件在一个步骤中完成此操作。
如果你写这样的东西:
int x = a[3];
然后编译器在编译时知道在哪里寻找变量,因此它可以在编译时设置相对和精确的内存位置。处理器不需要计算变量在内存中的位置。
"从内存地址到达开始,向前走 3 个内存地址。获取 在该内存地址处表示的整数。
所以基本上,这是真的,但这样写只是出于教育目的。在这种情况下,处理器不会这样做。
通过哈希表访问元素时,将根据键计算哈希值。许多键可能会导致相同的哈希值。因此,必须有一个位置存储许多具有相同哈希值的对象,该位置称为存储桶。因为一个存储桶中可能有很多对象,所以必须搜索所有对象才能找到您要查找的值,但这仍然比将所有值存储在数组中(您必须遍历其所有元素(要快得多。
这本质上就是数组访问的工作方式,它非常快。哈希表并不比数组快;事实上,正是因为它们接近与数组一样快的速度,所以它们被认为是非常快的。哈希表的主要优点是可以使用任何可哈希类型作为键,而不仅仅是整数。此外,它们支持稀疏数据,中间没有一堆浪费的数组空间。
它们的访问效率并不比阵列高。
这并没有说太多,因为数组的速度快得令人眼花缭乱。索引数组(即从一个对象到该数组中的随机另一个对象(是 O(1( - 单个加法操作。大多数处理器甚至有专门的指令,用于以各种形式索引到数组和子对象中,这些指令可以做得更好。
处理器不会在途中遍历每个地址 - 它会跳过它们,无论有多少个地址。"与阵列访问一样高效"确实是高度赞扬。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 使用前向材料(而不是双向术语)在硬件级别上做什么
- 任何地方都可以测试arduino在没有硬件的情况下能做什么
- 测试操作系统性能时,硬件开销和软件开销有什么区别
- 当我访问数组的元素时,在硬件级别会发生什么
- 查找硬件中正在使用的中断驱动程序的命令是什么?
- 将变量作为指针、引用、常量引用等传递:硬件级别会发生什么
- 填充硬件输入结构以与 SendInput 一起使用的正确方法是什么
- 我需要什么硬件/软件移植我的c++ /wxWidgets应用程序到MAC