简体   繁体   English

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

[英]How can i speed up this python code?

So I recently coded this as a little challenge to see how quick I could do it.所以我最近把它编码为一个小挑战,看看我能多快做到。 Now since its working an such I want to speed it up.现在,由于它的工作如此,我想加快速度。 It finds all the proper devisors of a number, the highest proper devisor and times how long it all takes.它找到一个数的所有真除数、最高的真除数和时间。 The problem is with number like 5000 it takes 0.05 secs but with numbers like 99999999999 it takes 1567.98 secs.问题是像 5000 这样的数字需要 0.05 秒,但是像 99999999999 这样的数字需要 1567.98 秒。

this the old code I have made a new and improved version below这是我在下面制作了一个新的和改进的版本的旧代码

import time导入时间

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()

Can someone speed it up for me有人可以帮我加快速度吗

EDIT 1编辑 1

so after looking over it I have now edited it to be moving it away from a file to an array因此,在查看它之后,我现在对其进行了编辑,将其从文件移至数组

    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

New Edit新编辑

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

If you have divisor a of number n then you can tell one more divisor of n b = n / a .如果您有数n除数a ,那么您可以再告诉一个n b = n / a除数。 Moreover if a <= sqrt(n) then b >= sqrt(n) and vice versa.此外,如果a <= sqrt(n)那么b >= sqrt(n)反之亦然。 It means in your finddivisor function you can iterate while i * i <= n and print both divisors i and n / i .这意味着在您的finddivisor函数中,您可以迭代i * i <= n并打印除数in / i By the way, you shouldn't open, read and close files in cycle.顺便说一句,您不应该循环打开、读取和关闭文件。 Open it once before cycle and close after if you need to read/write several times.如果您需要多次读/写,请在循环前打开它并在循环后关闭它。

You don't need to read and rewrite the entire file every time you want to put a single entry into it.每次要在其中放入一个条目时,您都不需要读取和重写整个文件。 You can just do it once when you know what change you want.当你知道你想要什么改变时,你可以只做一次。 Also you could just append to it.你也可以附加到它。 Maybe something like this:也许是这样的:

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))

also your program flow is building a very deep stack.您的程序流也在构建一个非常深的堆栈。 Try and flatten it with something like尝试用类似的东西压平它

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")

in properdivisor you dont need to read the whole file either, you just need the first line.properdivisor中,您也不需要读取整个文件,您只需要第一行。 so maybe something like:所以也许是这样的:

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)

AFTER EDIT编辑后

Something like this is how I would do it, and it runs less then a second on my box:我会这样做,它在我的盒子上运行不到一秒钟:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM