【问题标题】:How to input a huge string of integer array in Python in less memory heap如何在更少的内存堆中在 Python 中输入一个巨大的整数数组字符串
【发布时间】:2020-09-15 16:28:39
【问题描述】:

我有一个输入测试文件

10000000
1 23 53 64 599 -645 746 84 944 10 ..(10000000 integers)

我用来输入的python3代码如下

t = int(input())
a = [int(i) for i in input().split()]

由于第 2 行太大,我的程序需要大量 RAM(短时间间隔

int a;
cin >> a;
bitset<10000000> visited;
while (a--)
{
    int x;
    scanf("%d",&x);
    visited[x] = true;
}

仅使用 7MB。有什么办法可以减少这种情况吗?获取整数输入而不立即将整个字符串加载到内存中(如部分加载字符串)?

【问题讨论】:

  • 当然可以。标准输入流为sys.stdin;您可以从中读取字符,例如.read(64) 一次读取 64 个字符(或二进制流的字节)。
  • link 这会帮助你!
  • 有没有办法读取一定数量的整数?这可能会在中途读取一个整数
  • @Snowfox 您也可以使用.read(1) 一次只读取一个字节,但效率会降低。

标签: python python-3.x


【解决方案1】:

不,您一直在编写自己的输入流处理程序。您将需要读取一个缓冲区(您选择的缓冲区大小),split 尽您所能,并在行尾保存任何部分整数。

例如:

leftover = ''

while True:
    buffer = leftover + sys.stdin.read(64)
    str_num = buffer.split()
    if buffer[-1] != ' ':
        leftover = str_num.pop(-1)
    new_values = [int(i) for i in str_num]
    # process new values

当您遇到 EOF 时,捕捉/检测条件。

【讨论】:

    【解决方案2】:

    扩展我的 cmets:

    根据 psutil 的说法,这个实现总共需要大约 26 兆字节的 RSS 内存,其中在 read_file() 期间分配了 10 兆字节。

    (作为额外的奖励,由于我们可以使用每个整数的完整字节内存,我们可以准确计算每个整数有多少(除非我们溢出了 8 位......)。)

    import random
    import array
    import psutil
    
    
    def read_file(inf):
        n = int(inf.readline())
        # Preallocate an array.
        # TODO: this uses one byte per `n`, not one bit.
        # The allocation also takes some additional temporary memory
        # due to the list initializer.
        arr = array.array("b", [0] * n)
    
        input_buffer = ""
        nr = 0
        while True:
            # Read a chunk of data,
            read_buffer = inf.read(131072)
            # Add it to the input-accumulating buffer
            input_buffer += read_buffer
            # Partition the accumulating buffer from the right,
            # and swap the "rest" (after the last space) to be
            # the new accumulating buffer.
            process_chunk, sep, input_buffer = input_buffer.rpartition(" ")
            if not process_chunk:  # Nothing to process anymore
                break
            for value in process_chunk.split(" "):
                arr[int(value)] += 1
                nr += 1
        assert n == nr
        return arr
    
    
    mi0 = psutil.Process().memory_info()
    
    with open("output.txt", "r") as inf:
        arr = read_file(inf)
    
    mi1 = psutil.Process().memory_info()
    print("initial memory usage", mi0.rss)
    print("final memory usage..", mi1.rss)
    print("delta from initial..", mi1.rss - mi0.rss)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 2014-11-18
      • 2014-04-18
      • 1970-01-01
      • 2013-02-15
      相关资源
      最近更新 更多