2014-04-07 106 views
0

我正在制作一个素数计算器,它的工作原理非常完美,但我希望通过使用多线程来加快速度。我想知道你们中的任何一个人是否可以用某些资源指向我的某个地方(python文档不是很有帮助),或者在我的代码中给我一个例子。制作程序多线程

import time 
#Set variables 
check2 = 0 
check3 = 0 
check5 = 0 
check7 = 0 
#get number 
primenum = int(input("What number do you want to find out whether it is prime or not?\nIt must be a natural number\n**Calculations may take some time depending of the power of the computer and the size of the number**\n")) 
#set divisor 
primediv = primenum - 2 
#assume it's prime until proven innocent 
prime = 1 
#Create variable for GUI 
working = "Calculating" 
work = 10000000 
#set the number of divides to 0 
divnum = 0 
#start the clock 
starttime = time.perf_counter() 
#until it is not prime or divided by 1... 
while prime == 1 and primediv >7: 
    #does simple checks to deal with large numbers quickly 
    #Does this by dividing with small numbers first 
    if primenum != 0 and check2 == 0: 
     primemod = primenum % 2 
     check2 = 1 
     print(working + ".") 
     working = working +"." 
    elif primenum != 0 and check3 == 0: 
     primemod = primenum % 3 
     check3 = 1 
     print(working + ".") 
     working = working +"." 
    elif primenum != 0 and check5 == 0: 
     primemod = primenum % 5 
     check5 = 1 
     print(working + ".") 
     working = working + "." 
    elif primenum != 0 and check7 == 0: 
     primemod = primenum % 7 
     check7 = 1 
     print(working + ".") 
     working = working + "." 
    #divde and get remainder 
    else: 
     primemod = primenum % primediv 
     #Working visuals 
     if divnum == work: 
      print(working + ".") 
      working = working +"." 
      work = work + 10000000 
    #if the can't be devided evenly 
    if primemod == 0: 
     #then it isn't a prime 
     prime = 0 
    else: 
     #if it can, keep going 
     primediv = primediv - 2 
     divnum = divnum + 1 
#print results 
if prime == 1: 
    print("That number is prime") 
    print ("It took ", time.perf_counter()-starttime, " seconds to perform that calculation\n") 
else: 
    print("That number is not prime") 
    print ("It took ", time.perf_counter()-starttime, " seconds to perform that calculation\n") 
+0

你可以开始[这里](http://stackoverflow.com/questions/2846653/python-multithreading-for-dummies),[这里](http://stackoverflow.com/questions/11899224/multithreading-in -python)和[here](http://stackoverflow.com/questions/6469462/python-multithreading)。 :) – Manhattan

+4

请注意,多线程(Python)不会使任何东西运行更快。它不使用多个处理器线程,它只运行在多个操作线程中。 –

+1

同时深入研究[Eratosthenes的筛选器](http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)进行素数检查。它比你的强力方法指数更快。 –

回答

4

最流行的Python实现(CPython和PyPy)带有全局解释器锁(“GIL”)。这样做的目的基本上是为了简化内存管理。它的效果是只有一次线程可以执行Python字节码。因此对于使用Python进行所有计算的程序来说,线程不会使速度更快。

通常情况下最好的是让程序更快,就是到找到更好的算法。看例如在此:

def prime_list(num): 
    """Returns a list of all prime numbers up to and including num. 

    :num: highest number to test 
    :returns: a list of primes up to num 

    """ 
    if num < 3: 
     raise ValueError('this function only accepts arguments > 2') 
    candidates = range(3, num+1, 2) # (1) 
    L = [c for c in candidates if all(c % p != 0 for p in range(3, c, 2))] #(2) 
    return [2] + L # (3) 

(1)偶数> 2可以除以2,因此它们不能是素数,不需要考虑。 (2):对于奇数c为素数,必须确保c模以前的所有奇数(p)必须不为零。

(3):2也是一个素数。

一个小小的改进是p只需要上升到sqrt(c)

def prime_list2(num): 
    if num < 3: 
     raise ValueError('this function only accepts arguments > 2') 
    candidates = range(3, num+1, 2) 
    L = [c for c in candidates if all(c % p != 0 for p in 
     range(3, int(math.sqrt(c))+1, 2))] 
    return [2] + L 

请注意,我使用列表内涵代替for循环,因为它们普遍较快。

最后,亚当斯密提到的一种筛子;

def prime_list3(num): 
    num += 1 
    candidates = range(3, num, 2) 
    results = [2] 
    while len(candidates): 
     t = candidates[0] 
     results.append(t) 
     candidates = [i for i in candidates if not i in range(t, num, t)] 
    return results 

要看哪一个更快,我们需要运行测试;

首先为num=100

In [8]: %timeit prime_list(100) 
1000 loops, best of 3: 185 µs per loop 

In [9]: %timeit prime_list2(100) 
10000 loops, best of 3: 156 µs per loop 

In [10]: %timeit prime_list3(100) 
1000 loops, best of 3: 313 µs per loop 

然后1000:

In [11]: %timeit prime_list(1000) 
100 loops, best of 3: 8.67 ms per loop 

In [12]: %timeit prime_list2(1000) 
1000 loops, best of 3: 1.94 ms per loop 

In [13]: %timeit prime_list3(1000) 
10 loops, best of 3: 21.6 ms per loop 

然后10000;

In [14]: %timeit prime_list(10000) 
1 loops, best of 3: 680 ms per loop 

In [15]: %timeit prime_list2(10000) 
10 loops, best of 3: 25.7 ms per loop 

In [16]: %timeit prime_list3(10000) 
1 loops, best of 3: 1.99 s per loop 

在这些算法中,似乎最好。

+1

+1我个人从未遇到过Python太慢而无法做我想做的事情的问题。 (虽然这样的问题肯定存在)。每当我的应用程序很慢,总是因为算法不好。 –