如何使用装饰器监视程序消耗的内存

时间:2016-12-29 10:30:36

标签: python python-2.7 python-3.x memory memory-management

我构建了一个用于查找素数的算法(sieve of Eratosthenes),但它消耗了大量内存。目前,我的代码使用装饰器来监视时间的黯然失色。你能想出一个类似的装饰来评估我的程序所消耗的内存吗?

    import math
    import time


    def time_usage(func):
        def wrapper(*args, **kwargs):
            beg_ts = time.time()
            result = func(*args, **kwargs)
            end_ts = time.time()
            print("[INFO] elapsed time: %f" % (end_ts - beg_ts))
            return result
        return wrapper

    @time_usage
    def find_prime(n):
        is_composite = [False for _ in range(n + 1)]
        # Cross out multiples of 2
        for i in range(4, n, 2):
            is_composite[i] = True
        # Cross out multiples of primes found so far
        next_prime = 3
        stop_at = math.sqrt(n)
        while next_prime < stop_at:
            # Cross out multiples of this prime
            for i in range(next_prime * 2, n, next_prime):
                is_composite[i] = True
            # Move the next prime, skipping the even number
            next_prime += 2
            while next_prime <= n and is_composite[next_prime]:
                next_prime += 2
        # Copy the primes into a list
        primes = []
        for i in range(2, n):
            if not is_composite[i]:
                primes.append(i)

        return primes


    if __name__ == '__main__':
        print(find_prime(100000))

一个建议是使用第三方库来分析内存使用情况。我使用了memory_profiler,因为它提供了一个很好的装饰器实现,但我不能同时使用time_usage装饰器和内存配置文件。

在这里,我可以看到@profile实际上正在分析time_usage的记忆。

import math
import time
from memory_profiler import profile


def time_usage(func):
    def wrapper(*args, **kwargs):
        beg_ts = time.time()
        result = func(*args, **kwargs)
        end_ts = time.time()
        print("[INFO] elapsed time: %f" % (end_ts - beg_ts))
        return result
    return wrapper

@profile
@time_usage
def find_prime(n):
    is_composite = [False for _ in range(n + 1)]
    # Cross out multiples of 2
    for i in range(4, n, 2):
        is_composite[i] = True
    # Cross out multiples of primes found so far
    next_prime = 3
    stop_at = math.sqrt(n)
    while next_prime < stop_at:
        # Cross out multiples of this prime
        for i in range(next_prime * 2, n, next_prime):
            is_composite[i] = True
        # Move the next prime, skipping the even number
        next_prime += 2
        while next_prime <= n and is_composite[next_prime]:
            next_prime += 2
    # Copy the primes into a list
    primes = []
    for i in range(2, n):
        if not is_composite[i]:
            primes.append(i)

    return primes


if __name__ == '__main__':
    print(find_prime(100000))

制作:

  

Line#Mem使用量增加行内容

 7     27.4 MiB      0.0 MiB       def wrapper(*args, **kwargs):
 8     27.4 MiB      0.0 MiB           beg_ts = time.time()
 9     28.3 MiB      0.9 MiB           result = func(*args, **kwargs)
10     28.3 MiB      0.0 MiB           end_ts = time.time()
11     28.3 MiB      0.0 MiB           print("[INFO] elapsed time: %f" % (end_ts - beg_ts))
12     28.3 MiB      0.0 MiB           return result
     

[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,   67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,   ......,99989,99991]

1 个答案:

答案 0 :(得分:-1)

Python有很多内存分析器。 This answer列出了其中一些内容。

您可以创建一个装饰器,在函数调用之前检查内存使用情况,在函数调用之后显示差异。只要你在一个线程中运行,就应该得到你想要的结果。