读取一种类型的文本文件,里面内容是这样的:
00401000 56 8D 44 24 08 50 8B F1 E8 94 B7 01 00 C7 06 74
00401010 BE 54 00 8B C6 5E C2 04 00 CC CC CC CC CC CC CC
00401020 C7 01 74 BE 54 00 E9 9E B8 01 00 CC CC CC CC CC
00401030 56 8B F1 C7 06 74 BE 54 00 E8 8B B8 01 00 F6 44
00401040 24 08 01 74 09 56 E8 E4 BA 01 00 83 C4 04 8B C6
00401050 5E C2 04 00 CC CC CC CC CC CC CC CC CC CC CC CC
00401060 8B 44 24 08 C3 CC CC CC CC CC CC CC CC CC CC CC
00401070 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
00401080 8B 44 24 08 66 8B 08 8B 54 24 04 66 89 0A C3 CC
00401090 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
.....
有好几十万行。
我想把后面那些 16 进制的数字依次转换成 10 进制,存到一个 list 里。
我现在代码读取很慢,读一个文件要几十分钟
with open(f"{file_name}", "r") as rd:
arr = []
for line in tqdm(rd.readlines()):
arr.extend([int(f"0x{a}", 16) for a in line.strip().split(" ")[1:]])
return np.array(arr, dtype=np.ubyte)
有没有更快的方法,求大佬解答
1
ysc3839 2022-05-06 21:52:29 +08:00 via Android
没太看懂你的需求和代码,你是要转成十进制整数字符串吗?代码中好像没有相关操作
至于解决的话,试试改成流式处理,即不要预先读取过多数据 |
2
zxCoder OP @ysc3839 [int(f"0x{a}", 16) for a in line.strip().split(" ")[1:]] 我这里是把一行的十六进制转成十进制的。太多行了,跑半天
|
3
ynyounuo 2022-05-06 22:15:02 +08:00
你这个需求似乎没有必要 serial
|
5
imn1 2022-05-06 22:31:22 +08:00
|
6
ysc3839 2022-05-06 22:38:11 +08:00 via Android
@zxCoder 你这是转成整数,整数在计算机里是二进制的,并不是十进制。一般提到十进制、十六进制等指的都是相应进制的数字文本。
|
8
dcsuibian 2022-05-06 22:44:19 +08:00
很久没接触 Python 了,看不太懂 arr.extend
你这一行是 56 个字符,加一个回车一行 57 个。都是 ascii 算一个字节。一行就 57 个字节。算一百万行,就是 57x100x10000/1024/1024=54.3MB ,这么小的量。 直接读进来放内存里,一秒都不到,明显是你这处理方式有问题。 |
9
dcsuibian 2022-05-06 22:47:19 +08:00
而且仔细看才发现,你这 rd.readlines()函数调用的时候就已经全部读到内存了。
|
10
clino 2022-05-06 22:50:19 +08:00
读取应该花不了太多时间,但是处理数据花的时间会比较多,你可以把处理数据的代码去掉测试一下看看。
|
11
chi1st 2022-05-06 22:57:33 +08:00
用 pandas
|
12
misaka19000 2022-05-06 23:19:34 +08:00
先看一下瓶颈在哪啊,是 CPU 满了还是内存满了
|
13
wangyongbo 2022-05-06 23:56:19 +08:00
你可以把你的文件发出来,让大家测试一下吗?
|
14
ysc3839 2022-05-07 04:09:07 +08:00 1
用你给的数据重复了 500000 次(你给的数据有十行,总共有五百万行了)输出到文件,然后用你的代码去掉 tqdm 后在本地跑了下,也就耗时 23 秒,哪要几十分钟?
自己写的代码耗时 5 秒 ``` with open('test.txt', 'r') as f: arr = bytearray() for line in f: i = line.find(' ') if i == -1: print('!') break arr.extend(bytes.fromhex(line[i + 1:])) print(len(arr)) ``` 空格请自行补全 |
15
yzwduck 2022-05-07 07:40:59 +08:00
@ysc3839 如果不介意多耗一点内存的话,这样写的代码会跑得更快。
``` with open('test.txt', 'r') as fi: data.fi.read() arr = bytes.fromhex(re.sub(r'^[0-9A-Fa-f]+ ', '', data, flags=re.MULTILINE)) ``` |
16
BingoXuan 2022-05-07 09:41:58 +08:00
想起客户提供的同行的烂代码,处理 30 秒 wave 文件要 35 秒
pattern = re.compile('[0-9A-F]{2}') def read_file(name): ----with open(name,'r') as f: --------while True: ------------l = f.readline() ------------if not l: ----------------break ------------for x in pattern.findall(l): ----------------yield int(x,16) result = [y for y in read_file('some file')] |