【发布时间】:2020-07-10 22:29:53
【问题描述】:
我们有一个二维列表,如有必要,我们可以将其转换为任何内容。每行包含一些正整数(原始递增数字的增量)。总共 20 亿个数字,其中一半以上等于 1。当使用Elias-Gamma 编码时,我们可以根据每个数字使用大约 3 位逐行编码 2d 列表(稍后我们将使用行索引访问任意行)从分布计算。然而,我们的程序已经运行了 12 个小时,它仍然没有完成编码。 以下是我们正在做的事情:
from bitstring import BitArray
def _compress_2d_list(input: List[List[int]]) -> List[BitArray]:
res = []
for row in input:
res.append(sum(_elias_gamma_compress_number(num) for num in row))
return res
def _elias_gamma_compress_number(x: int) -> BitArray:
n = _log_floor(x)
return BitArray(bin="0" * n) + BitArray(uint=x, length=_log_floor(x) + 1)
def log_floor(num: int) -> int:
return floor(log(num, 2))
调用者:
input_2d_list: List[List[int]] # containing 1.5M lists, total 2B numbers
compressed_list = _compress_2d_list(input_2d_list)
如何优化我的代码以使其运行得更快?我的意思是,快得多......我可以使用任何可靠的流行库或数据结构。
另外,我们如何使用BitStream 更快地解压?目前我一个一个地读取前缀0,然后在while循环中读取压缩数字的二进制文件。也不是很快……
【问题讨论】:
-
我猜这里写一个 C 扩展不是一个选项?
-
是的,可能不是……
-
我会说 C++ 而不是 C(使用 pybind11 或 Boost.Python 应该不会花费太多时间)。或者尝试像 Cython 这样的东西,但这可能需要更长的时间来哄你做你需要的。您的主要敌人是解释器,每条语句的执行都涉及大量开销……正如您清楚地看到的那样,开销加起来超过 20 亿次迭代。
标签: python algorithm numpy compression