2017-04-14 7 views
1

주어진 데이터 세트에 두 개의 인접 요소가있는 특정 함수를 적용하려고합니다. 다음 예제를 참조하십시오. 한 번에 파이썬에서 다중 작업

# I'll just make a simple function here. 
# In my real case, I send request to database 
# to get the result with two arguments. 

def get_data_from_db_with(arg1, arg2): 
    # write a query with arg1 and arg2 named 'query_result' 
    return query_result 

data = [arg1, arg2, arg3, arg4] 
result = [] 
for a, b in zip(data, data[1:]): 
    result.append(get_data_from_db_with(a, b)) 

데이터의 길이가 상기 볼의 경우와 같이 4이면

후 I 데이터베이스에 요청을 3 회 보내. 각 요청은 데이터를 검색하는 데 약 0.3 초가 걸리므로 총 0.9 초 (0.3 초 ​​* 3 요청)입니다. 문제는 요청 수가 증가하면 전반적인 시간도 증가한다는 것입니다. 가능한 경우 모든 요청을 한 번에 보냅니다. 기본적으로, 이렇게 보일 것입니다. 위의 코드

,

1) get_data_from_db_with(arg1, arg2) 
2) get_data_from_db_with(arg2, arg3) 
3) get_data_from_db_with(arg3, arg4) 

연속적으로 처리된다.


가능한 경우 연속해서가 아니라 모든 요청을 한꺼번에 보내는 것입니다. 물론 요청 수는 변하지 않습니다. 그러나 전반적인 시간 소비는 내 가정에 따라 감소 할 것입니다.

이제 비동기, 다중 처리 등을 찾고 있습니다. 의견이나 피드백은 대단히 도움이 될 것입니다.

미리 감사드립니다.

답변

2

아마도 당신이 찾고있는 스레드 일 것입니다. get_data_from_db_with 작업의 대부분이 데이터베이스 호출과 같이 I/O를 기다리고 있다고 가정합니다.

import threading 

def get_data_from_db_with(arg1, arg2): 
    # write a query with arg1 and arg2 named 'query_result' 
    current_thread = threading.current_thread() 
    current_thread.result = query_result 

data = [arg1, arg2, arg3, arg4] 
threads = [] 
for a, b in zip(data, data[1:]): 
    t = threading.Thread(target=get_data_from_db_with, args=(a,b)) 
    t.start() 
    threads.append(t) 

results = [] 
for t in threads: 
    t.join() 
    results.append(t.result) 

이 솔루션은 results 목록에도 순서를 유지합니다.

+0

귀하의 조언에 감사드립니다! 'threading' 사용에 관한 질문이 있습니다. 필자가 아는 한, Python은 GIL (전역 인터프리터 잠금)을 제공하는 멀티 스레드보다 멀티 프로세싱을 선호합니다. 내가 틀릴 수도 있지만, 단지 호기심이 많았습니다. –

+0

@GeeYeolNahm 전적으로 당신이하려는 일에 달려 있습니다. GIL은 모든 I/O에서 출시되므로 대부분의 시간 동안 I/O (CPU 집약적 인 작업을 수행함)를 수행하면 스레드가 프로세스보다 우선적으로 수행됩니다. – freakish

+0

멀티 스레딩 테스트를 시도했는데 성공했습니다!. 평균 2 ~ 3 배 빠릅니다. 그래, 네 말이 맞아, 멀티 스레딩은 내 작업 환경에서이 경우에 효과가 있었다. 다시 한 번 고마워! –

1

다중 처리의 대안은 쿼리 생성 자체에 대한 작업입니다. 기본적으로 (arg1 and arg2) or (arg2 and arg3)...과 같은 쿼리를 결합하는 방법을 찾으려면 본질적으로 단일 호출에서 필요한 모든 데이터를 가져 오려고합니다.

+0

생각해 주셔서 감사합니다. 네, 언급 한 것처럼 하나의 요청을 보내는 검색을 수행했습니다. 나는 여전히 단일 쿼리를 작성하고 결과를 파싱하는 중이다. 나는 [elasticserach multisearch API] (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html)를 사용하고 있습니다. 무엇보다도 하나의 요청을 동시에 여러 요청을 보내는 것보다 실적이 좋다고 생각합니다. –