第1章 · 内存视角看NumPy 本章要回答的三个问题:同样是存一千万个数,为什么 Python 列表又慢又费内存、NumPy 数组却快得多?ndarray 到底由哪几块东西组成?装好环境之后,我该从哪个属性开始"看"一个数组? 为什么会有这一章 几乎每本 NumPy 教材开头都说"NumPy 很快,因为它是 C 写的"。这话对,但没用——它解释不了为什么切片一个数组改的是原数组,解释不了为什么 dtype 不对会静默丢数据,更解释不了为什么有人 transpose 之后代码反而变慢。快不快的根源不在"用什么语言写的",而在数据在内存里怎么摆。 列表里存的是一个个对象的地址,地址指向的东西散落在堆的各处;ndarray 是一整块连续内存,元素一个挨一个躺着。
本章要回答的三个问题:同样是存一千万个数,为什么 Python 列表又慢又费内存、NumPy 数组却快得多?ndarray 到底由哪几块东西组成?装好环境之后,我该从哪个属性开始"看"一个数组?
几乎每本 NumPy 教材开头都说"NumPy 很快,因为它是 C 写的"。这话对,但没用——它解释不了为什么切片一个数组改的是原数组,解释不了为什么 dtype 不对会静默丢数据,更解释不了为什么有人 transpose 之后代码反而变慢。快不快的根源不在"用什么语言写的",而在数据在内存里怎么摆。
列表里存的是一个个对象的地址,地址指向的东西散落在堆的各处;ndarray 是一整块连续内存,元素一个挨一个躺着。这个差别是全书所有内容的起点,本章用两节把它讲透:第一节做实验,亲手量出列表与数组的差距;第二节拆开 ndarray,认识它的三要素。
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 1.1 为什么Python列表跑不快 | 性能差距从哪来 | 列表 vs 数组的计时与内存实验 |
| 1.2 ndarray的三要素 | 数组由什么构成 | 内存示意图 + 三要素解读套路 |
读完本章,以下知识点应当达到"能向别人讲清楚"的程度,每条都可以在代码里当场验证:
问:不学内存原理,直接背 API 不行吗?
答:能应付小数据,但一旦数据上千万行,"为什么这段慢""为什么内存爆了""为什么原数组被改了"这类问题会密集出现,而它们的答案全在布局里。与其每次事故查论坛,不如一次学透。
问:C 语言基础需要吗?
答:完全不需要。本册讲的"内存"只到"连续字节块加描述字段"这一层,配上图解就能建立模型,不涉及指针语法或编译细节。
问:实验数据在我的机器上不一样怎么办?
答:不一样才是正常的——计时受硬件影响,但结论方向(倍数差距、共享内存与否)在所有机器上一致。关注结论而非具体毫秒数。
本章结束时你看到的还只是"数组是一块连续内存加几个描述字段"。第 2 章会继续深入这块内存:元素如何被定位(步长)、两种摆放顺序(C 序与 F 序)、以及贯穿全书的那把尺子——视图还是拷贝。