這是上一篇文件<<使用 python 把一個文件生成 C 語言中的數組並保存到頭文件中>>續,
在測試的時候,突然發現了一個現象,就好像是一道光,給了我一個解決轉換大文件慢的問題的靈感,這個現象是從轉換率的變化率一開始很快然后開始變慢,如下:
從上圖看,轉換到 60% 左右還很快,然后就變得很慢了。
目前得做法是,把轉換出來得數據都放到一個字符串中,等轉換結束后,一次性寫入文件,上面看到轉化率的過程,都是在讀取、轉換、添加到字符串,這 3 個步驟前 2 給都試過了,解決不了轉換慢的問題,那會不會是在第 3 個步驟呢,
來、測試下,思路是每轉換一定數量后,先保存進文件中,一直重復這 2 個步驟,直到轉換完成。
首先,前面部分代碼還是跟之前一樣,先判斷輸入參數中是否包含待處理文件,及待處理文件是否存在:
if __name__ == "__main__":
if len(sys.argv) != 2:
print("argv is not 2")
exit()
print(sys.argv[0] + "," + sys.argv[1])
if os.path.exists(sys.argv[1]) is False:
print("file not exit")
exit()
start_time = time.time()
filepath = sys.argv[1]
print("The file is:" + sys.argv[1])
if "\\" in filepath:
filename = filepath.split("\\")[-1].split(".")[0]
else:
filename = filepath.split(".")[0]
filename_upper = filename.upper()
然后實現一個保存數據的函數:
def save_data2header(filename,dat):
path = filename + ".h"
file = open(path,"a+")
file.write(dat)
file.close()
因為把數據保存到文件中也是分開來的,每次寫文件是往文件后面添加數據,所以打開文件時使用以 “a+” 方式打開,然后先把頭文件前面部分寫進文件:
header = "#ifndef __" + filename_upper + "_H__\n"
header = header + "#define __" + filename_upper + "_H__\n\n"
header = header + "const uint8_t " + filename + "[] = {\n"
save_data2header(filename,header)
然后是讀取、轉換、保存:
fileinfo = os.stat(filepath)
line = fileinfo.st_size / 16
target = ""
f = open(filepath, "rb")
count = 0
for l in range(int(line)):
for j in range(16):
data = f.read(1)
he = "0x" + data.hex()
target = target + he + ","
target = target + "\n"
count = count +1
if count == 1000:
save_data2header(filename,target)
count = 0
target = ""
print("\rrate of progress: %f%% " % (l *100 / line), end="")
save_data2header(filename,target)
f.close()
這里做法是沒轉換 1000 行就保存一次,最后添加頭文件尾部、計算所花時間:
header_end = "};" + "\n#endif\n"
save_data2header(filename,header_end)
end_time = time.time()
print("\nLast time:",end="")
print(end_time - start_time)
運行結果如下:
這一次居然才用了差不多 37 秒,算了下未優化前居然是這次的 825.5 倍:
實在是太讓人震驚了。
這是什么原因呢?
想了下,之前的做法,時間是耗在了往 python 的字符變量添加數據上,這字符變量使用的是什么結構體,往字符變量上添加數據使用的是什么算法,也許搞懂了這些就知道原因在哪了。