Python многоядерный медленнее, чем одноядерный - PullRequest
1 голос
/ 17 февраля 2020

Я пытаюсь сравнить однопоточную и многопоточную производительность и закодировал проверку простого числа.

Это всего лишь две функции, одна работает в обычном однопоточном режиме, а другая использует python параллельный модуль и пытается поставить в очередь кучу процессов, чтобы проверить, является ли число простым или нет.

Дело в том, что в однопоточном режиме он работает намного быстрее, чем в многопоточном.

Вот мой код:

import time, os, math, threading
from concurrent import futures

N = 1000

pList = []
pListM = []

processes = []
ex = futures.ProcessPoolExecutor()

def isPrime(n):
    if n < 2:
        return (n,False)
    if n == 2:
        return (n,True)
    if n % 2 == 0:
        return (n,False)

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return (n,False)
    return (n,True)

def firstPrimes(n):
        initTime = time.perf_counter()
        global pList
        i = 0
        while len(pList) < n:
                if isPrime(i): 
                        pList.append(i)
                i = i+1
        totalTime = time.perf_counter() - initTime
        print(pList)
        print("Single-Threaded it took ",totalTime," seconds to find the first ",N," primes.")

def done(fn):
    global N
    if fn.cancelled():
        print('{}: canceled'.format(fn))
    elif fn.done():
        error = fn.exception()
        if error:
            print('{}: error returned: {}'.format(
                fn.arg, error))
        else:
            result = fn.result()
##            print("\nEl resultado fue ",result,"\n")
##            print("Will pop index: ", result[0])
            processes.remove([result[0],fn])
            if result[1] and len(pListM) < N:
                    pListM.append(result[0])
##                    print("La lista de primos es: ",pListM)


def firstPrimesM(n):
        initTime = time.perf_counter()
        global pListM
        global processes
        global ex
        i = 0

        while len(pListM) < n:
                if len(processes) < 16:
##                        print("submiting process ",i)
                        pro = ex.submit(isPrime, i)
                        pro.add_done_callback(done)
                        processes.append([i,pro])
##                        print(processes)
                        i = i + 1
        for i, pro in reversed(processes):
                if not pro.cancel():
                        print('did not cancel {}'.format(i))
        ex.shutdown()
        totalTime = time.perf_counter() - initTime
        print(pListM)
        print("Multi-Threaded it took ",totalTime," seconds to find the first ",N," primes.")

if __name__ == '__main__':
        try:
                firstPrimes(N)
                firstPrimesM(N)
        except KeyboardInterrupt:
            print("User exited with Ctrl + C")
            for i, pro in reversed(processes):
                if not pro.cancel():
                        print('did not cancel {}'.format(i))
            ex.shutdown()

Любая помощь будет очень признательна!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...