作者icetofux ()
看板Python
标题[问题] list中插入资料效能的问题
时间Tue Feb 21 12:31:54 2017
假设有个list中有上百万笔资料, 我希望每隔1024笔就插入32笔0xFF, 写了程式
如下:
def AppendData(raw_list):
# 制作一个空 list 用来存放资料.
new_list = list()
# 制作一个32笔0xFF的list当作插入用的资料.
insert_data = 32*[0xFF]
for addr in range(0, len(raw_list), 1024):
# 列出处里进度, 平时会关掉以加快处理速度.
print(addr)
# 以1024笔为单位将资料复制到新list并插入32笔0xFF.
new_list = new_list + raw_list[addr:(addr+1024)] + insert_data
return (new_list)
已结果来看目的是达成了可是效率奇差无比, 目前光是4百万笔的测试用资料就要跑将
近1分钟, 未来实际使用时资料量可能是数十倍甚至百倍.
请问像这样的需求有更好的写法吗?
谢谢.
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 211.72.212.239
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1487651517.A.CBD.html
1F:→ os653: 用字串的join方法试试?你用+的可能会一直要记忆体喔 02/21 13:07
目前修改一下程式观察是哪个步骤在吃时间:
def AppendData(raw_list):
# 制作一个空 list 用来存放资料.
new_list = list()
# 制作一个32笔0xFF的list当作插入用的资料.
insert_data = 32*[0xFF]
for addr in range(0, len(raw_list), 1024):
# 列出处理进度, 平时会关掉以加快处理速度.
t1 = time.time()
print(address)
# 以1024笔为单位将资料复制到新list并插入32笔0xFF.
t2 = time.time()
temp = raw_list[addr:(addr+1024)]
t3 = time.time()
new_list = new_list + temp + insert_data
t4 = time.time()
print("print:", (t2-t1), ", slice:", (t3-t2), ", list add:", (t4-t3))
return (new_list)
output:
print: 0.0 , slice: 0.0 , list add: 0.015630722045898438
意外的slice不怎麽花时间, 所以时间应该都是用在把资料加入新的list.
或许一开始先把新的list所需空间算好做出来, 再用raw_data去replace会比较好,
因为这样就不用一直要记忆体了:
def AppendDataV2(raw_list):
# 制作一个空 list 用来存放资料.
new_list_size = int((len(raw_list)/1024)*(1024+32))
new_list = new_list_size * [0xFF]
for addr in range(0, len(raw_list), 1024):
# 列出处理进度, 平时会关掉以加快处理速度.
print(addr)
# 以raw_list中1024笔为单位取代new_list中的资料.
new_start = (int((addr/1024)*(1024+32)))
new_stop = new_start + 1024
new_list[new_start:new_stop] = raw_list[addr:(addr+1024)]
return (new_list)
处理4百万笔资料时间从95.8秒降至1.6秒, 效果十分显着.
感谢两位帮忙, 虽然我没有去尝试使用字串及join来处理, 但从两位的建议中找到了
方向, 十分感谢.
推 Yshuan: 要快就是转string builder处理再转回来
※ 编辑: icetofux (211.72.212.239), 02/21/2017 14:09:06
2F:→ huei820504: 为什麽不直接用insert? 03/06 03:05