일부 계산을 병렬 처리하려고하는데 왜 내 버전 (내가 더 빨라야한다고 생각했는지)이 느린 이유를 이해하지 못합니다.Python, 알고리즘을 병렬 처리하는 데 도움이 됨 (스레드 풀 내부에서 스레드 풀을 갖기 위해 노력)
간략하게 말하자면, userIds 목록 (200 개 이하)과 placesId (2,000,000 개 이하) 목록이 있습니다. 각 쌍 사용자/장소에 대한 점수를 계산해야합니다. 은 계산이 서로 완전히 독립적이며 알고리즘을 구현하는 방법에 따라 결과가 더 필요하지 않다는 결론을 얻었습니다.
나는 이것을 위해 2 가지 방법을 시도했습니다.
,451,515,첫 번째 방법
- 풀 ALL 내 작은 맥북 8 내 경우에는
루프 모든 사용자와 산란 X 스레드를 통해 메인 스레드에서 장소와 모든 사용자가 (될 것으로 보인다) 최고의
모든 선물이 (작업자의 작업 목록 [userId를, placeId를 돌려 그들 모두를 통해 I 루프를 완료하고 데이터베이스에 을 결과를 삽입하는with cf.ThreadPoolExecutor(max_workers=8) as executor: futures = [executor.submit(task,userId, placeIds) for userId in userIds]
, 점수])
나는 모든 장소를 통해 루프는이 여자와 부드러운 사람이 계산되는 사용자/장소의 모든 설정을 만드는 결과
def task(userId, placeIds): connection = pool.getconn() cursor = conn.cursor() #loop through all the places and call makeCalculation(cur, userId, placeId) pool.putconn(conn) return results
을 반환하는 작업을 10 분 (순차적 방식으로 1.30 시간 대신)
그러나 그렇다면 왜 점수 계산을 병렬 처리할까요? 따라서 2000 개의 모든 장소를 한 번씩 반복해야하는 작업 대신 다른 8 개의 스레드에 계산을 생성하십시오.
두 번째 방법 :
기본적으로이 방식에 의해 "작업"함수에서 루프를 대체 : 내가해야 할 일을했을
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
futures = [ executor.submit(calculateScores,userId,placeId) for placeId in placeIds]
다른 수정은 calculateScores이 기능에
def calculateScores(userId,placeId):
**connection = pool.getconn()
cursor = connecton.cursor()**
...
make a bunch of calculation by calling the database 1 or 2 times
pool.putconn(conn)
return [userId, placeId, score]
이제 calculateScores 자체가 8 //에 있기 때문에 볼 수 있듯이 // thr eads 그래서 나는 데이터베이스 연결을 공유 할 수 없다. 그렇지 않으면 경합 조건 오류가 발생한다. (그리고 스크립트는 4 번 중 3 번 중 하나가 충돌 할 것이다)
이 접근법은 더 빠른 bu가 25 분이 소요될 것이라고 생각했다. ... (단순한 for 루프를 사용하는 10 대신 ...)
모든 작업이 이제 풀에서 데이터베이스 연결을 가져오고 이것이 다소 비용이 많이 들고 느려서 느려지므로 90 %가 느립니다.
내 시나리오에서 병렬 처리를 최대한 활용하는 가장 좋은 방법은 누군가에게 조언을 줄 수 있습니까?
작업 결과를 얻는 것이 좋습니까? 또는 calculateScores 함수가 준비되면 바로 데이터베이스에 삽입해야합니까?
ThreadPool 안에 Threadpool을 설치하는 것이 좋습니다.
몇 가지 다중 프로세스를 실행해야합니까?
감사합니다.
GIL을 알고 있습니까? 제가 아는 가장 좋은 설명은 David Beazley입니다 : http://www.dabeaz.com/python/UnderstandingGIL.pdf – cdarke
제가 생각하기는하지만 분명히 아닙니다. 첫 번째 예제는 두 번째 접근 방식이 더 느린 이유에 대한 부분입니다. 프로세스를 사용하기 시작했다해도? – Johny19
같은 문장의 스레드와 파이썬 ... 나쁜 징조 –