Heim  >  Artikel  >  Backend-Entwicklung  >  So beschleunigen Sie das häufige Schreiben von Dateien in Python

So beschleunigen Sie das häufige Schreiben von Dateien in Python

尚
Original
2019-06-26 14:52:352914Durchsuche

So beschleunigen Sie das häufige Schreiben von Dateien in Python

Problemhintergrund: Es gibt eine Reihe von Dateien, die verarbeitet werden müssen. Für jede Datei muss die gleiche Funktion zur Verarbeitung aufgerufen werden, was ziemlich zeitaufwändig ist.

Gibt es eine Möglichkeit, es zu beschleunigen? Wenn Sie diese Dateien beispielsweise in mehrere Stapel aufteilen, ruft jeder Stapel ein von Ihnen geschriebenes Python-Skript zur Verarbeitung auf, sodass auch die gleichzeitige Ausführung mehrerer Python-Programme beschleunigt werden kann.

Gibt es einen einfacheren Weg? Zum Beispiel wird ein Programm, das ich ausführe, gleichzeitig in mehrere Threads aufgeteilt und dann verarbeitet?

Allgemeine Idee: Teilen Sie diese Dateipfadlisten in mehrere Teile auf. Die Anzahl der Teile hängt davon ab, wie viele Kerne Ihre CPU hat. Wenn Ihre CPU beispielsweise 32 Kerne hat, ist dies theoretisch möglich um das 32-fache beschleunigt werden.

Der Code lautet wie folgt:

# -*-coding:utf-8-*-
import numpy as np
from glob import glob
import math
import os
import torch
from tqdm import tqdm
import multiprocessing
label_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/label.txt'
file_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/distortion_image'
save_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/flow_field'
r_d_max = 128
image_index = 0
txt_file = open(label_path)
file_list = txt_file.readlines()
txt_file.close()
file_label = {}
for i in file_list:
    i = i.split()
    file_label[i[0]] = i[1]
r_d_max = 128
eps = 1e-32
H = 256
W = 256
def generate_flow_field(image_list):
    for image_file_path in ((image_list)):
        pixel_flow = np.zeros(shape=tuple([256, 256, 2]))  # 按照pytorch中的grid来写
        image_file_name = os.path.basename(image_file_path)
        # print(image_file_name)
        k = float(file_label[image_file_name])*(-1)*1e-7
        # print(k)
        r_u_max = r_d_max/(1+k*r_d_max**2)  # 计算出畸变校正之后的对角线的理论长度
        scale = r_u_max/128  # 将这个长度压缩到256的尺寸,会有一个scale,实际上这里写128*sqrt(2)可能会更加直观
        for i_u in range(256):
            for j_u in range(256):
                x_u = float(i_u - 128)
                y_u = float(128 - j_u)
                theta = math.atan2(y_u, x_u)
                r = math.sqrt(x_u ** 2 + y_u ** 2)
                r = r * scale  # 实际上得到的r,即没有resize到256×256的图像尺寸size,并且带入公式中
                r_d = (1.0 - math.sqrt(1 - 4.0 * k * r ** 2)) / (2 * k * r + eps)  # 对应在原图(畸变图)中的r
                x_d = int(round(r_d * math.cos(theta)))
                y_d = int(round(r_d * math.sin(theta)))
                i_d = int(x_d + W / 2.0)
                j_d = int(H / 2.0 - y_d)
                if i_d < W and i_d >= 0 and j_d < H and j_d >= 0:  # 只有求的的畸变点在原图中的时候才进行赋值
                    value1 = (i_d - 128.0)/128.0
                    value2 = (j_d - 128.0)/128.0
                    pixel_flow[j_u, i_u, 0] = value1  # mesh中存储的是对应的r的比值,在进行畸变校正的时候,给定一张这样的图,进行找像素即可
                    pixel_flow[j_u, i_u, 1] = value2
# 保存成array格式
        saved_image_file_path = os.path.join(save_path, image_file_name.split(&#39;.&#39;)[0] + &#39;.npy&#39;)
        pixel_flow = pixel_flow.astype(&#39;f2&#39;)  # 将数据的格式转换成float16类型, 节省空间
        # print(saved_image_file_path)
        # print(pixel_flow)
        np.save(saved_image_file_path, pixel_flow)
    return
if __name__ == &#39;__main__&#39;:
    file_list = glob(file_path + &#39;/*.JPEG&#39;)
    m = 32
    n = int(math.ceil(len(file_list) / float(m)))  # 向上取整
    result = []
    pool = multiprocessing.Pool(processes=m)  # 32进程
    for i in range(0, len(file_list), n):
        result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))
    pool.close()
    pool.join()

Im obigen Code muss die Funktion

generate_flow_field(image_list)

a übergeben Liste, und dann für Diese Liste betreiben und dann die Ergebnisse des Vorgangs speichern

Sie müssen also nur die mehreren Dateien, die Sie verarbeiten müssen, in möglichst gleich große Listen aufteilen und dann eine öffnen Thread für jede Liste verarbeiten.

Die obige Hauptfunktion:

if __name__ == &#39;__main__&#39;:
    file_list = glob(file_path + &#39;/*.JPEG&#39;)  # 将文件夹下所有的JPEG文件列成一个list
    m = 32  # 假设CPU有32个核心
    n = int(math.ceil(len(file_list) / float(m)))  # 每一个核心需要处理的list的数目
    result = []
    pool = multiprocessing.Pool(processes=m)  # 开32线程的线程池
    for i in range(0, len(file_list), n):
        result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))  # 对每一个list都用上面我们定义的函数进行处理
    pool.close()  # 处理结束之后,关闭线程池
    pool.join()

Hauptsächlich zwei Zeilen Code wie diese, eine Zeile wird

pool = multiprocessing.Pool(processes=m)  # 开32线程的线程池

zum Öffnen des Threads verwendet pool

Zusätzlich Eine Zeile ist

result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))  # 对每一个list都用上面我们定义的函数进行处理

Verwenden Sie für den Thread-Pool apply_async(), um gleichzeitig die Funktion „generate_flow_field“ auszuführen. Die übergebenen Parameter sind: file_list[i: i+ n]

Tatsächlich ist die Funktion apply_async() Die Funktion besteht darin, dass alle Threads gleichzeitig ausgeführt werden und die Geschwindigkeit relativ hoch ist.

Weitere technische Artikel zum Thema Python finden Sie in der Spalte Python-Tutorial, um mehr darüber zu erfahren!

Das obige ist der detaillierte Inhalt vonSo beschleunigen Sie das häufige Schreiben von Dateien in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn