python - 为什么泡菜比 np.save 花费这么多时间?
问题描述
我想保存一个dict
或数组。
我尝试了 withnp.save
和 with pickle
,发现前者总是花费更少的时间。
我的实际数据要大得多,但我只是在这里展示一小部分用于演示目的:
import numpy as np
#import numpy.array as array
import time
import pickle
b = {0: [np.array([0, 0, 0, 0])], 1: [np.array([1, 0, 0, 0]), np.array([0, 1, 0, 0]), np.array([0, 0, 1, 0]), np.array([0, 0, 0, 1]), np.array([-1, 0, 0, 0]), np.array([ 0, -1, 0, 0]), np.array([ 0, 0, -1, 0]), np.array([ 0, 0, 0, -1])], 2: [np.array([2, 0, 0, 0]), np.array([1, 1, 0, 0]), np.array([1, 0, 1, 0]), np.array([1, 0, 0, 1]), np.array([ 1, -1, 0, 0]), np.array([ 1, 0, -1, 0]), np.array([ 1, 0, 0, -1])], 3: [np.array([1, 0, 0, 0]), np.array([0, 1, 0, 0]), np.array([0, 0, 1, 0]), np.array([0, 0, 0, 1]), np.array([-1, 0, 0, 0]), np.array([ 0, -1, 0, 0]), np.array([ 0, 0, -1, 0]), np.array([ 0, 0, 0, -1])], 4: [np.array([2, 0, 0, 0]), np.array([1, 1, 0, 0]), np.array([1, 0, 1, 0]), np.array([1, 0, 0, 1]), np.array([ 1, -1, 0, 0]), np.array([ 1, 0, -1, 0]), np.array([ 1, 0, 0, -1])], 5: [np.array([0, 0, 0, 0])], 6: [np.array([1, 0, 0, 0]), np.array([0, 1, 0, 0]), np.array([0, 0, 1, 0]), np.array([0, 0, 0, 1]), np.array([-1, 0, 0, 0]), np.array([ 0, -1, 0, 0]), np.array([ 0, 0, -1, 0]), np.array([ 0, 0, 0, -1])], 2: [np.array([2, 0, 0, 0]), np.array([1, 1, 0, 0]), np.array([1, 0, 1, 0]), np.array([1, 0, 0, 1]), np.array([ 1, -1, 0, 0]), np.array([ 1, 0, -1, 0]), np.array([ 1, 0, 0, -1])], 7: [np.array([1, 0, 0, 0]), np.array([0, 1, 0, 0]), np.array([0, 0, 1, 0]), np.array([0, 0, 0, 1]), np.array([-1, 0, 0, 0]), np.array([ 0, -1, 0, 0]), np.array([ 0, 0, -1, 0]), np.array([ 0, 0, 0, -1])], 8: [np.array([2, 0, 0, 0]), np.array([1, 1, 0, 0]), np.array([1, 0, 1, 0]), np.array([1, 0, 0, 1]), np.array([ 1, -1, 0, 0]), np.array([ 1, 0, -1, 0]), np.array([ 1, 0, 0, -1])]}
start_time = time.time()
with open('testpickle', 'wb') as myfile:
pickle.dump(b, myfile)
print("--- Time to save with pickle: %s milliseconds ---" % (1000*time.time() - 1000*start_time))
start_time = time.time()
np.save('numpy', b)
print("--- Time to save with numpy: %s milliseconds ---" % (1000*time.time() - 1000*start_time))
start_time = time.time()
with open('testpickle', 'rb') as myfile:
g1 = pickle.load(myfile)
print("--- Time to load with pickle: %s milliseconds ---" % (1000*time.time() - 1000*start_time))
start_time = time.time()
g2 = np.load('numpy.npy')
print("--- Time to load with numpy: %s milliseconds ---" % (1000*time.time() - 1000*start_time))
这给出了一个输出:
--- Time to save with pickle: 4.0 milliseconds ---
--- Time to save with numpy: 1.0 milliseconds ---
--- Time to load with pickle: 2.0 milliseconds ---
--- Time to load with numpy: 1.0 milliseconds ---
对于我的实际大小(字典中的约 100,000 个键),时差更加明显。
为什么 pickle 比 np.save 需要更长的时间来保存和加载?
我应该什么时候使用pickle
?
解决方案
因为只要写入的对象不包含 Python 数据,
- numpy 对象在内存中的表示方式比 Python 对象简单得多
- numpy.save 是用 C 编写的
- numpy.save 以需要最少处理的超简单格式写入
同时
- Python 对象有很多开销
- pickle 是用 Python 编写的
- pickle 将数据从内存中的底层表示显着转换为写入磁盘上的字节
请注意,如果 numpy 数组确实包含 Python 对象,那么 numpy 只会腌制数组,所有的胜利都会消失。
推荐阅读
- prolog - 将包含原子的表达式输出到列表中的谓词
- influxdb - Telegraf 插件 - Telegraf 仅针对一个插件向 influxdb 发送数据
- mysql - Laravel Eloquent - 自动编号有很多关系
- search - 我只是想做搜索功能。在这个搜索函数中,一个字符通过 find() 与数组中的所有元素进行比较。的
- jsp - 当我在jsp中使用会话时出现一个springboot奇怪的状态500问题
- cryptography - 如何在 ERC20 或 BEP20 智能合约中添加“交易费”?
- c - C 转换结构的返回值
- jquery - jQuery 外部函数参数在每个循环中不可见
- node.js - 当graphQL的查询从mongodb返回空数据时,你应该检查什么?
- html - 尽管自动溢出,flexbox 的内容仍然溢出