【问题标题】:Making a Program Multithreaded使程序多线程
【发布时间】:2014-05-20 03:05:43
【问题描述】:

我正在制作一个素数计算器,它运行良好,但我希望它通过使用多线程来更快。我想知道你们中是否有人可以指出我有一些资源的地方(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")

【问题讨论】:

  • 您可以开始hereherehere。 :)
  • 请注意,多线程(在 Python 中)不会让任何东西运行得更快。它不使用多个处理器线程,它只是在多个操作线程中运行。
  • 还可以深入查看Sieve of Eratosthenes 以检查素数。它比你的蛮力方法快得多。
  • 如果我们暂时忽略任何 python 细节,请注意多线程 != 更快。您可以从头开始将程序设计为多线程,并利用特定的硬件使程序运行得更快。但是仅仅让一个程序多线程并不能让它自动更快(在某些情况下它可能工作得更慢)。此外,它为大量程序引入了全新级别的复杂性,要​​么破坏它们,要么使它们更难理解和维护。

标签: python python-3.x


【解决方案1】:

最流行的 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

在这些算法中,prime_list2 似乎表现得最好。

【讨论】:

  • +1 我个人从未遇到过 Python 太慢而无法执行我想要的操作的问题。 (虽然这样的问题确实存在。)每当我的应用程序运行缓慢时,总是因为算法不好。
猜你喜欢
  • 1970-01-01
  • 2012-05-26
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多