我怎样才能加速这个python代码?

时间:2014-04-18 14:47:56

标签: python performance python-2.7 python-3.x

所以我最近将此编码为一个小挑战,看看我能做多快。现在,因为它的工作,我想加快它。它找到了一个数字的所有正确的设计者,最高的适当的设计者和所需的时间。问题是像5000这样的数字需要0.05秒,但是像99999999999这样的数字需要1567.98秒。

这个旧代码我在

下面制作了一个新的改进版本

导入时间

def clearfile(name):
    file = open(name + ".txt", "r")
    filedata = file.read()
    file.close()
    text_file = open(name + ".txt", "w")
    text_file.write("")
    text_file.close()

def start():
    num = input("Enter your Number: ")
    check(num)

def check(num):
    try:
        intnum = int(num)
    except ValueError:
        error(error = "NON VALID NUMBER")
    if(intnum < 0):
        error(error = "POSITIVE NUMBERS ONLY")
    else:
        finddivisor(intnum)

def finddivisor(intnum):
    starttimer = time.time()
    i = 1
    print("\nThe divisors of your number are:"),
    while i <= intnum:
        if (intnum % i) == 0:
            print(i)
            file = open("numbers.txt", "r")
            filedata = file.read()
            file.close()
            text_file = open("numbers.txt", "w")
            text_file.write(str(i) +"\n"+ filedata)
            text_file.close()
        i += 1
    properdivisor(starttimer)

def properdivisor(starttimer):
    file = open("numbers.txt", "r")
    highest = file.readlines()
    print("\nThe Highest Proper Divisor Is\n--------\n" + highest[1] + "--------" + "\nIt took"  ,round(time.time() - starttimer, 2)  ,"seconds to finish finding the divisors.\n")
    restart(errorrestart = "false")

def restart(errorrestart):
    if errorrestart == "false":
        input("Do You Want Restart?\nPress Enter To Restart Or Close The Programe To Leave")
        start()
    elif errorrestart == "true":
        input("\nThere Was An Error Detected.\nPress Enter To Restart Or Close The Programe To Leave")
        start()

def error(error):
    print("\n----------------------------------\nERROR - " + error + "\n----------------------------------")
    restart(errorrestart = "true")

clearfile(name = "numbers")
start()

有人可以为我加速吗

编辑1

所以在查看之后我现在编辑它以将其从文件移动到数组

    import time
    from array import *
    def programme():
        num = input("Enter your Number: ")
        try:
            intnum = int(num)
        except ValueError:
           error("NOT VALID NUMBER")
        if(intnum < 0):
            error("POSITIVE NUMBERS ONLY")
        else:
                numbers = array("i",[])
                starttimer = time.time()
                i = 1
                print("\nThe divisors of your number are:"),
                while i <= intnum:
                    if (intnum % i) == 0:
                        numbers.insert(0,i)
                        print(i)
                    i += 1
                print("\nThe Highest Proper Divisor Is\n--------\n" + str(numbers[1]) + "\n--------" + "\n\nIt took"  ,round(time.time() - starttimer, 2)  ,"seconds to finish finding the divisors.\n")    
    def error(error):
        print("\n----------------------------------\nERROR - " + error + "\n----------------------------------\n")
    running = True
    while(running == True):
        programme()
        print("----------------------------------")
        restart = input("Do You Want Restart?")
        restart = restart.lower()
        if restart in ("yes", "y", "ok", "sure", ""):
            print("Restarting\n----------------------------------")
        else:
            print("closing Down")
            running = False

新编辑

import time, math
from array import *
def programme():
    num = input("Enter your Number: ")
    try:
        intnum = int(num)
        if(intnum < 0):
            error("POSITIVE NUMBERS ONLY")
        else:
            numbers = array("i",[])
            starttimer = time.time()
            i = 1
            print("\nThe divisors of your number are:"),
            while i <= math.sqrt(intnum):
                if (intnum % i) == 0:
                    numbers.insert(0,i)
                    numbers.insert(0,int(intnum/i))
                    print(i,":", int(intnum/i))
                i += 1
            numbers = sorted(numbers, reverse = True)
            print("The Highest Proper Divisor Is\n--------\n",str(numbers[1]) , "\n--------\nIt took"  ,round(time.time() - starttimer, 2)  ,"seconds to finish finding the divisors." )
    except ValueError:
       error("NOT VALID NUMBER")
    except OverflowError:
       error("NUMBER IS TO LARGE")
    except:
       error("UNKNOWN ERROR")

def error(error):
    print("\n----------------------------------\nERROR - " + error + "\n----------------------------------\n")
running = True
while(running):
    programme()
    print("----------------------------------")
    restart = input("Do You Want Restart?")
    restart = restart.lower()
    if restart in ("yes", "y", "ok", "sure", ""):
        print("Restarting\n----------------------------------")
    else:
        print("closing Down")
        running = False

2 个答案:

答案 0 :(得分:2)

如果你有[{1}}数字a的除数,那么你可以再告诉n n一个除数。此外,如果b = n / a然后a <= sqrt(n),反之亦然。这意味着在您的b >= sqrt(n)函数中,您可以在finddivisor时进行迭代,并打印除数i * i <= ni。 顺便说一句,您不应该在循环中打开,读取和关闭文件。如果需要多次读/写,请在循环前打开一次,然后关闭。

答案 1 :(得分:0)

每次要将单个条目放入其中时,无需读取和重写整个文件。当你知道你想要什么改变时,你可以做一次。你也可以附加它。也许是这样的:

def finddivisor(intnum):
    starttimer = time.time()
    print("\nThe divisors of your number are:")
    divs = set()
    for i in range(1, int(math.sqrt(intnum)) +1):
        if intnum % i == 0:
            print(i)
            divs.add(i)
            divs.add(intnum // i)
    with open("numbers.txt", "a") as file:
        file.writelines("{}\n".format(ln) for ln in sorted(divs, reverse=True))

你的程序流程也在构建一个非常深的堆栈。尝试用

之类的东西压扁它
def start():
    clearfile()
    while True:
        n = get_number()
        starttimer = time.time()
        finddivisor(n)
        properdivisor(starttimer)
        input("Press Enter To Restart Or Close The Programe To Leave")

properdivisor你也不需要阅读整个文件,你只需要第一行。所以可能是这样的:

def properdivisor(starttimer):
    with open(FILENAME, "r") as file:
        highest = file.readline().strip()
    print "\nThe Highest Proper Divisor Is"
    print "--------%s--------" % highest
    print "It took %0.2f seconds to finish finding the divisors.\n" % (time.time() - starttimer)

编辑后

这样的事情就是我如何做到的,它在我的盒子上运行的时间少于一秒:

import math

def get_divisors(n):
    yield 1
    sqroot = int(math.sqrt(n))
    for x in xrange(2, sqroot):
        if n % x == 0:
            yield x
            yield n / x
    if sqroot**2 == n:
        yield sqroot

divisors = sorted(get_divisors(999999999999))
print divisors