2011-01-12 5 views
5

큰 데이터 구조, 특히 더 큰 사전을 사용하여 찾고있는 작업을 수행해야합니다. 맨 처음 내 코드에서Python의 함수에서 큰 데이터 구조를 사용할 때의 효율성

은 다음과 같이이다 : 나는 많은 시간을 볼 필요로

#build the dictionary 
blablabla 
#look up some information in the ditionary 
blablabla 

, 나는 함수로 구현하는 것이 좋습니다 것을 깨닫기 시작, 조회 말 (정보).

다음은 큰 사전을 어떻게 처리해야합니까?

내가 인수로 전달하는 조회 (정보, 사전)를 사용하는 경우, 또는 그냥 주()에 사전을 초기화해야하며, 단지 전역 변수로 사용?

글로벌 변수를 유지하는 것이 번거롭기 때문에 첫 번째 방법이 더 우아 해 보입니다. 그러나 다른 한편으로, 큰 사전을 함수에 전달하는 효율성에 대해서는 확신 할 수 없습니다. 논쟁의 여지가 비효율적이라면, 그것은 여러 번 호출 될 것이고, 분명히 악몽이 될 것입니다.

감사합니다.

EDIT1가 :

이 여기에 코드의 조각이다 :

난 그냥 위의 두 가지 방법으로 실험을했다. lookup1 lookup2가 전역 데이터 구조 "big_dict"를 사용하는 동안 조회를 전달하는 인수가에 구현됩니다.

lookup1가 은 그래서 그 두 가지 방법을 보인다 lookup2이 클래스는 4.525721

8.157661
입니다 8.410885

:

class CityDict(): 
    def __init__(): 
     self.code_dict = get_code_dict() 
    def get_city(city): 
     try: 
      return self.code_dict[city] 
     except Exception: 
      return None   

def get_code_dict(): 
    # initiate code dictionary from file 
    return code_dict 

def lookup1(city, city_code_dict): 
    try: 
     return city_code_dict[city] 
    except Exception: 
     return None 

def lookup2(city): 
    try: 
     return big_dict[city] 
    except Exception: 
     return None 


t = time.time() 
d = get_code_dict() 
for i in range(0, 1000000): 
    lookup1(random.randint(0, 10000), d) 

print "lookup1 is %f" % (time.time() - t) 


t = time.time() 
big_dict = get_code_dict() 
for i in range(0, 1000000): 
    lookup2(random.randint(0, 1000)) 
print "lookup2 is %f" % (time.time() - t) 


t = time.time() 
cd = CityDict() 
for i in range(0, 1000000): 
    cd.get_city(str(i)) 
print "class is %f" % (time.time() - t) 

는 출력 거의 th이다 e와 같고 네, 글로벌 변수 방법은 좀 더 효율적입니다.

Edit2가 :

추가 된 황색 제안하고 다시 효율성을 테스트 클래스 버전. 그러면 우리는 앰버가 옳다는 결과를 볼 수있었습니다. 우리는 클래스 버전을 사용해야합니다.

+2

파이썬의 사전은 오히려 효율적이고 최대 20 억 개 항목까지 사용할 수 있습니다. 이 제한은 내부적으로 32 비트 만 사용하는 해시 때문입니다.이 시점에서 너무 많은 해시 충돌이 발생하기 시작합니다. 이 shuold는 Python 3.3에서 64 비트 아키텍처로 변경되었지만 더 이상이 제한을 갖지 않습니다. – jsbueno

답변

5

아니요. 데이터 (멤버)와 특별히 기능 (방법)을 그룹화를 위해 설계된 클래스 사용

class BigDictLookup(object): 
    def __init__(self): 
     self.bigdict = build_big_dict() # or some other means of generating it 
    def lookup(self): 
     # do something with self.bigdict 

def main(): 
    my_bigdict = BigDictLookup() 
    # ... 
    my_bigdict.lookup() 
    # ... 
    my_bigdict.lookup() 
+0

감사! 나는 바로 이것을 시도 할 것이다. – ibread

+1

감사! 검증되었고 클래스가 더 나은 선택임을 알게되었습니다. – ibread

8

핵심 질문에 대답을, 매개 변수 전달은 당신의 값이 주변에 카피 한 것처럼하지 비효율적 없습니다. 파이썬은 매개 변수가 전달되는 방식이 "값에 의한 전달"또는 "참조에 의한 전달"이라는 잘 알려진 방식에 적합하다는 것을 말하는 것이 아니라 참조를 전달했습니다.

호출자가 제공 한 참조 값을 사용하여 호출 된 함수의 로컬 변수 값을 값으로 전달하는 것으로 상상하는 것이 가장 좋습니다.

그래도 클래스를 사용하는 것이 좋습니다.

+2

그래, 모든 것이 파이썬에서 참조로 전달됩니다. 구조체는 함수에 전달 될 때 복사되지 않습니다. 사전을 원하는만큼 크게 만들 수 있으며 명시 적으로 지정하지 않으면 사전을 복사하지 않습니다. – MarkR

+0

OP가 C 백그라운드에서 마이그레이션 중이라고 추측하고 있습니다. – smci

+1

@MarkR : 아니요, 모든 것은 파이썬에서 가치에 의해 전달됩니다. 객체는 단순히 값이 아닙니다. 모든 값은 참조입니다. – newacct

관련 문제