大气的课本 · 美国媒体:外观时尚、奔驰座舱、宝马性能,想要 ...· 1 年前 · |
阳刚的玉米 · 浙江省人民政府办公厅关于加强避灾安置场所规范 ...· 1 年前 · |
曾深爱过的毛衣 · 浙江传媒学院招聘现场美女如云_频道_凤凰网· 1 年前 · |
性感的仙人掌 · 铁血战士猎物影评解析_头条· 1 年前 · |
沉着的跑步鞋 · 斗罗大陆真人_斗罗大陆真人版投资了多少亿_斗 ...· 1 年前 · |
在使用Python3的flask应用程序中,我需要保存一次并加载多次大型数组。我最初将这些数组存储在json库的磁盘上。为了加快速度,我在同一台机器上使用Redis通过将数组序列化为JSON字符串来存储该数组。我想知道为什么我没有得到改进(实际上它在我使用的服务器上花费了更多的时间),而Redis将数据保存在RAM中。我猜JSON序列化没有优化,但我不知道如何加快速度:
import json
import redis
import os
import time
current_folder = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_folder, "my_file")
my_array = [1]*10000000
with open(file_path, 'w') as outfile:
json.dump(my_array, outfile)
start_time = time.time()
with open(file_path, 'r') as infile:
my_array = json.load(infile)
print("JSON from disk : ", time.time() - start_time)
r = redis.Redis()
my_array_as_string = json.dumps(my_array)
r.set("my_array_as_string", my_array_as_string)
start_time = time.time()
my_array_as_string = r.get("my_array_as_string")
print("Fetch from Redis:", time.time() - start_time)
start_time = time.time()
my_array = json.loads(my_array_as_string)
print("Parse JSON :", time.time() - start_time)
结果:
JSON from disk : 1.075700044631958
Fetch from Redis: 0.078125
Parse JSON : 1.0247752666473389
编辑 :看起来从redis获取数据实际上很快,但是JSON解析相当慢。有没有一种方法可以不使用JSON序列化部分直接从Redis获取数组?这就是我们对pyMySQL所做的,而且速度很快。
更新:2019年11月8日-在Python3.6上运行相同的测试
结果:
转储时间 :JSON > msgpack > > marshal
加载时:JSON > pickle > msgpack > marshal
空间包:编组> JSON >> msgpack
+---------+-----------+-----------+-------+
| package | dump time | load time | size |
+---------+-----------+-----------+-------+
| json | 0.00134 | 0.00079 | 30049 |
| pickle | 0.00023 | 0.00019 | 20059 |
| msgpack | 0.00031 | 0.00012 | 10036 |
| marshal | 0.00022 | 0.00010 | 50038 |
+---------+-----------+-----------+-------+
我尝试了pickle vs json vs msgpack vs marshal。
Pickle比JSON慢得多。而且JSON 至少比 快4倍。MsgPack看起来是你最好的选择。
编辑:也尝试了编组。Marshal比JSON快,但比msgpack慢。
耗时:Pickle > JSON > Marshal > MsgPack
空间占用:>腌黄瓜> Json > MsgPack
import time
import json
import pickle
import msgpack
import marshal
import sys
array = [1]*10000
start_time = time.time()
json_array = json.dumps(array)
print "JSON dumps: ", time.time() - start_time
print "JSON size: ", sys.getsizeof(json_array)
start_time = time.time()
_ = json.loads(json_array)
print "JSON loads: ", time.time() - start_time
# --------------
start_time = time.time()
pickled_object = pickle.dumps(array)
print "Pickle dumps: ", time.time() - start_time
print "Pickle size: ", sys.getsizeof(pickled_object)
start_time = time.time()
_ = pickle.loads(pickled_object)
print "Pickle loads: ", time.time() - start_time
# --------------
start_time = time.time()
package = msgpack.dumps(array)
print "Msg Pack dumps: ", time.time() - start_time
print "MsgPack size: ", sys.getsizeof(package)
start_time = time.time()
_ = msgpack.loads(package)
print "Msg Pack loads: ", time.time() - start_time
# --------------
start_time = time.time()
m_package = marshal.dumps(array)
print "Marshal dumps: ", time.time() - start_time
print "Marshal size: ", sys.getsizeof(m_package)
start_time = time.time()
_ = marshal.loads(m_package)
print "Marshal loads: ", time.time() - start_time
结果:
JSON dumps: 0.000760078430176
JSON size: 30037
JSON loads: 0.000488042831421
Pickle dumps: 0.0108790397644
Pickle size: 40043
Pickle loads: 0.0100247859955
Msg Pack dumps: 0.000202894210815
MsgPack size: 10040
Msg Pack loads: 7.58171081543e-05
Marshal dumps: 0.000118017196655
Marshal size: 50042
Marshal loads: 0.000118970870972
一些解释:
只需将缓存文件存储在 tmpfs 上,您就可以用最少的更改来加速应用程序。它与Redis在同一台服务器上的设置非常接近。
同意@RoopakANelliat msgpack比JSON快4倍左右。格式更改将提高解析性能(如果可能)。
我开发
brain-plasma
就是为了这个原因--在Flask应用程序中快速加载和重新加载大对象。它是Apache Arrow可序列化对象的共享内存对象名称空间,包括由
pickle.dumps(...)
生成的
pickle
'd字节串。
$ pip install brain-plasma
$ plasma_store -m 10000000 -s /tmp/plasma # 10MB memory