Python每次都从文件中读取或在列表中存储值?

时间:2015-12-19 05:21:49

标签: python primes

我目前正在编写一个python脚本来通过暴力生成每个素数。我目前有一个包含素数的> 5Mb文件,当脚本运行时,它会附加它找到的任何新素数,这样文件就会越来越大。每次运行脚本时,此文件都会被读入一个列表,然后循环计算下一个数字是否为素数,否则任何新素数也会附加到此列表中。

我的问题是,每次运行脚本时是否最好将此文件加载到内存中,或者我是否应该在for循环中读取文件的下一行,根据要检查的数字处理该文件,然后加载下一行线?

前者创建一个大型列表保存在内存中但速度非常快,第二个会慢一些,因为每次循环迭代时它都必须读取文件,但我认为它不会在内存附近使用。

这是我的代码,它将配置文件作为一个参数,包含开始寻找素数的数字和读/写素数的文件:

import sys, math, time

def is_prime(num,primes):
    square = math.floor(math.sqrt(num))
    print('using all prime numbers up to %d' % square)
    for p in primes:
        if p <= square:
            print (p, end='\r')
            if (num % p) == 0:
                return False
        else:
            return True
    return True

def main(argv):
    if len(sys.argv) == 2:
        try:
            try:
                f = open(sys.argv[1], 'r+')
            except IOError:
                sys.exit('Error: File %s does not exist in the current directory...\nUsage: generate_primes.py <prime_file>' % sys.argv[1])
            f.close()

            f = open(sys.argv[1], 'r+')
            low = f.readlines()
            f.close()

            num_to_check = int(low[0].strip('\n'))
            file_name = low[1].strip('\n')
            print(num_to_check)
            print(file_name)

            if num_to_check % 2 == 0:
                num_to_check += 1

            f = open(file_name, 'a+')
            f.seek(0)
            primes = f.readlines()

            print('Processing Primes...')
            for key,i in enumerate(primes):
                primes[key] = int(primes[key].strip('\n'))

            if primes[-1] > num_to_check:
                num_to_check = primes[-1]
                print('Last saved prime is bigger than config value.\nDefaulting to largest saved prime... %d' % primes[-1])

            time.sleep(2)

            new_primes = 0

            while True:
                print('Checking: %s ' % str(num_to_check), end='')
                if is_prime(num_to_check,primes):
                    print('Prime')
                    f.write('%s\n' % str(num_to_check))
                    primes.append(num_to_check)
                    new_primes += 1
                else:
                    print('Composite')
                num_to_check += 2

        except KeyboardInterrupt:
            config_name = time.strftime('%Y%m%d-%H%M%S')
            print('Keyboard Interrupt: \n creating config file %s ... ' % config_name)
            c = open(config_name,'w')
            c.write('%d\n%s' % (num_to_check,file_name))
            c.close()
            f.close()
            print('Done\nPrimes Found: %d\nExiting...' % new_primes)
            sys.exit()


if __name__ == '__main__':
    main(sys.argv[1:])

注意:素数文件不能包含单独的1,否则每个数字都会合成。

我只关注从文件读取的一个问题是能够获得存储的最大素数的值(也就是读取文件中的最后一行)。

1 个答案:

答案 0 :(得分:1)

速度和内存的优化往往是不一致的。有些程序会使用大量内存,但速度很快(Chrome会为此付出代价),其他程序可能会反过来,许多程序试图在两者之间寻求平衡。选择什么应该主要围绕问题,用例,如果你是真正彻底的数据。

如果要一遍又一遍地运行脚本,那么延迟和低速会真正加起来......你可能想要专注于优化速度。如果脚本运行的时间超过一秒左右,并且用户必须无用地盯着屏幕直到完成才能继续...您可能希望专注于速度。如果您的行为是时间敏感的,那么事情可能需要实时发生,并且您不希望因过度延迟而陷入困境......您可能希望专注于速度。

如果脚本只是偶尔运行,并且主要在时间不敏感的环境中运行,最好是在某个地方的背景中,特别是在有限或低端硬件上...你可能想要专注于内存。

更具体地说明你的问题,我可以说我完全同意Kristjan的评论,5MB并不是那么多。现在看我的笔记本电脑上的任务管理器,我可以说我有两个从维基百科打开的标签,很久没有触及它们,他们使用33x,Facebook上的一个标签,类似的故事,但是280x, rubyMine(IDE)使用的是244x,活动监视器(任务管理器)本身使用的是33x,并且在20MB标记下发生的情况并不多,除了小系统的东西应该真正归为一类,以减少混乱,有些程序我认为我一周前关闭。如果你的应用程序的其余部分保持相对较低的内存占用,你不是针对弱或嵌入式硬件,很可能人们会更快地抱怨速度低于RAM中大约5MB的空间,特别是当你清理它时完成(更适用于较低级别的语言,但也许del可以在这里提供帮助)。

真的,只有你知道你正在使用的问题的限制。嗯,这可能不是真的,但我当然不了解它们。您将不得不在实施过程中调用对您来说重要的内容,这可能涉及到某处的妥协。对两种实现进行基准测试以量化速度增加可以帮助您证明一个决策胜过另一个决策,并且在一个平局中,当然也可以考虑实现的简易性。