加快Python中加密图像文件的解包速度

问题描述 投票:0回答:1

我目前正在从我用来从文件(以及其他信息)获取图像(2048x2048)的软件中解压加密文件。我目前可以做到这一点,但加载大约需要 1.7 秒。通常情况下这没问题,但我在每次迭代时加载 40 个左右的图像,而我在此模拟中的下一步是添加更多迭代。我一直在尝试使用 JIT 解释器,例如 pypy 和 numba。下面的代码只是一个较大对象中的一个函数,但它是我时间滞后最多的地方。

Pypy 可以工作,但是当我调用 numpy 函数时,它需要两倍的时间。所以我尝试使用numba,但它似乎不喜欢解包。我尝试在 pypy 中使用 numba,但这似乎也不起作用。我的代码有点像这样

from struct import unpack
import numpy as np

def read_file(filename: str, nx: int, ny: int) -> tuple:
    f = open(filename, "rb")
    raw = [unpack('d', f.read(8))[0] for _ in range(2*nx*ny)] #Creates 1D list

    real_image = np.asarray(raw[0::2]).reshape(nx,ny) #Every other point is the real part of the image
    imaginary_image = np.asarray(raw[1::2]).reshape(nx,ny) #Every other point +1 is imaginary part of image

    return real_image, imaginary_image

在我正常的Python解释器中,

raw
行大约需要1.7秒,其余的<0.5 seconds. If I comment out the numpy lines and just unpack in pypy, the
raw
操作大约需要0.3秒。但是,如果我执行重塑操作,则需要更长的时间(我知道这与 numpy 在 C 中优化并且需要更长的时间来转换有关)。

所以我刚刚发现了 numba,并想通过回到我的普通 python 解释器(CPython?)来尝试一下。如果我将

@njit
@vectorize
装饰器添加到函数中,我会收到以下错误消息

File c:\Users\MyName\Anaconda3\envs\myenv\Lib\site-packages\numba\core\dispatcher.py:468, in _DispatcherBase._compile_for_args(self, *args, **kws)
    464         msg = (f"{str(e).rstrip()} \n\nThis error may have been caused "
    465                f"by the following argument(s):\n{args_str}\n")
    466         e.patch_message(msg)
--> 468     error_rewrite(e, 'typing')
    469 except errors.UnsupportedError as e:
    470     # Something unsupported is present in the user code, add help info
    471     error_rewrite(e, 'unsupported_error')

File c:\Users\MyName\Anaconda3\envs\myenv\Lib\site-packages\numba\core\dispatcher.py:409, in _DispatcherBase._compile_for_args.<locals>.error_rewrite(e, issue_type)
    407     raise e
    408 else:
--> 409     raise e.with_traceback(None)

TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'unpack': Cannot determine Numba type of <class 'builtin_function_or_method'>

我可能读错了这个错误消息,但 Numba 似乎不喜欢内置函数? 我没有研究过任何其他选项,例如 Cython。有什么方法可以让 Numba 或 pypy 工作吗?我最感兴趣的是加快这个操作,所以我很想知道人们认为最好的选择是什么。我愿意探索 C++ 中的优化,但我不知道如何将两者联系起来

python numba jit pypy
1个回答
0
投票

这是一个带有

np.memmap
的版本:

import numpy as np


def create_test_binary_file(filename, nx=2048, ny=2048):
    arr = np.zeros(shape=2 * nx * ny, dtype=np.float64)
    arr[::2] = 1
    arr[1::2] = 2

    with open(filename, "wb") as f_out:
        f_out.write(arr.tobytes())


def read_file(filename, nx=2046, ny=2048):
    arr = np.memmap(filename, dtype=np.float64, mode="r", shape=2 * nx * ny)

    return arr[::2].reshape(nx, ny), arr[1::2].reshape(nx, ny)


create_test_binary_file("test.dat")

r, i = read_file("test.dat")
print(r, i, sep="\n\n")

打印:

[[1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 ...
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]]

[[2. 2. 2. ... 2. 2. 2.]
 [2. 2. 2. ... 2. 2. 2.]
 [2. 2. 2. ... 2. 2. 2.]
 ...
 [2. 2. 2. ... 2. 2. 2.]
 [2. 2. 2. ... 2. 2. 2.]
 [2. 2. 2. ... 2. 2. 2.]]
© www.soinside.com 2019 - 2024. All rights reserved.