使用ctypes实现数组类的效率是否高于Python原生lists?
用ctypes实现数组类和Python原生list的效率对比
先说结论:绝大多数场景下,自行基于ctypes封装的数组类效率不会超过Python原生list,仅在特定场景下有优势。
- 原生Python list的底层本身就是C语言实现的动态数组,内存分配、自动扩容、元素增删改查的核心逻辑全是编译后的机器码执行,经过了十几年的生产环境调优,Python层的调用开销已经压到了最低,普通场景下很难比它更快。
- ctypes数组的唯一优势是存储固定类型原生数据时的内存开销和连续内存缓存命中率:原生list每个元素存储的都是Python对象的指针,哪怕你存一个简单的整数,也要附带完整的Python对象头,64位系统下存100万个int的总内存开销能到30MB以上;而ctypes的C类型数组直接存原生二进制值,同样存100万个32位int只需要4MB内存,缓存命中率更高,纯批量数值读写的场景下性能更好。
- 如果你自己用Python代码给ctypes数组封装动态扩容、插入删除等动态数组逻辑,这部分逻辑是跑在Python解释器层面的,比原生list的C层面实现同逻辑慢2~10倍不等,频繁增删元素的场景下性能会被原生list拉开非常大的差距。
- 如果你的使用场景是纯批量数值运算,不需要频繁增删元素,也不用Python循环逐个操作元素,而是直接把ctypes数组传给C函数或者numpy做批量处理,那这种场景下ctypes数组的性能确实会比原生list更高。
简单性能参考(64位Python 3.10,操作100万条int数据):
单元素随机读写:原生list耗时1020ns/次,ctypes数组耗时3060ns/次
内存占用:原生list约32MB,ctypesc_int数组约4MB
头部插入1000个元素:原生list耗时约0.2ms,Python封装的ctypes动态数组耗时约3ms
内容的提问来源于stack exchange,提问作者user14354509
相关产品推荐
相关产品推荐

