2014-01-13 2 views
0

저는 파이썬 초보자입니다. 궁금하네요 ...이 두 (파이썬) 코드 샘플의 차이점은 무엇입니까?

1 : sample2는 sample1보다 조금 빠르고 메모리 사용량이 적습니까? (변수를 선언하고 지정하지 않기 때문에)

질문 2 : '빅'프로그램에 적합한 샘플은 어느 것입니까?는 (그것도 큰 프로그램의 차이를 문제인가?)

에는 sample1 :

session = request.session 
session['v1'] = 1 
session['v2'] = 2 
session['v2'] = 3 
if session['v1'] == 1: 
    session['v4'] = 4 

SAMPLE2 :

request.session['v1'] = 1 
request.session['v2'] = 2 
request.session['v2'] = 3 
if request.session['v1'] == 1: 
    request.session['v4'] = 4 

아니 조기 최적화를위한. 그냥 알기 위해서 ...

+2

컴퓨터에서 일부 테스트를 실행하십시오! 이러한 것들이 큰 루프에서 실행되지 않는다면 어떤 종류의 성능 차이도 볼 수 있을지는 의문입니다. 속성 조회가 파이썬에서 얼마나 비쌉니까? – dm03514

답변

5

첫 번째 코드는 입니다. request 및 해당 특성의 모든 조회를 피하기 때문에 더 빠릅니다.

In [6]: dis.dis(test_first) 
    2   0 LOAD_GLOBAL    0 (request) 
       3 LOAD_ATTR    1 (session) 
       6 STORE_FAST    0 (session) 

    3   9 LOAD_CONST    1 (1) 
      12 LOAD_FAST    0 (session) 
      15 LOAD_CONST    2 ('v1') 
      18 STORE_SUBSCR   

    4   19 LOAD_CONST    3 (2) 
      22 LOAD_FAST    0 (session) 
      25 LOAD_CONST    4 ('v2') 
      28 STORE_SUBSCR   

    5   29 LOAD_CONST    5 (3) 
      32 LOAD_FAST    0 (session) 
      35 LOAD_CONST    4 ('v2') 
      38 STORE_SUBSCR   

    6   39 LOAD_FAST    0 (session) 
      42 LOAD_CONST    2 ('v1') 
      45 BINARY_SUBSCR   
      46 LOAD_CONST    1 (1) 
      49 COMPARE_OP    2 (==) 
      52 POP_JUMP_IF_FALSE  68 

    7   55 LOAD_CONST    6 (4) 
      58 LOAD_FAST    0 (session) 
      61 LOAD_CONST    7 ('v4') 
      64 STORE_SUBSCR   
      65 JUMP_FORWARD    0 (to 68) 
     >> 68 LOAD_CONST    0 (None) 
      71 RETURN_VALUE 

대 : 바이트 코드의 차이를 참조하십시오

In [7]: dis.dis(test_second) 
    2   0 LOAD_CONST    1 (1) 
       3 LOAD_GLOBAL    0 (request) 
       6 LOAD_ATTR    1 (session) 
       9 LOAD_CONST    2 ('v1') 
      12 STORE_SUBSCR   

    3   13 LOAD_CONST    3 (2) 
      16 LOAD_GLOBAL    0 (request) 
      19 LOAD_ATTR    1 (session) 
      22 LOAD_CONST    4 ('v2') 
      25 STORE_SUBSCR   

    4   26 LOAD_CONST    5 (3) 
      29 LOAD_GLOBAL    0 (request) 
      32 LOAD_ATTR    1 (session) 
      35 LOAD_CONST    4 ('v2') 
      38 STORE_SUBSCR   

    5   39 LOAD_GLOBAL    0 (request) 
      42 LOAD_ATTR    1 (session) 
      45 LOAD_CONST    2 ('v1') 
      48 BINARY_SUBSCR   
      49 LOAD_CONST    1 (1) 
      52 COMPARE_OP    2 (==) 
      55 POP_JUMP_IF_FALSE  74 

    6   58 LOAD_CONST    6 (4) 
      61 LOAD_GLOBAL    0 (request) 
      64 LOAD_ATTR    1 (session) 
      67 LOAD_CONST    7 ('v4') 
      70 STORE_SUBSCR   
      71 JUMP_FORWARD    0 (to 74) 
     >> 74 LOAD_CONST    0 (None) 
      77 RETURN_VALUE 

공지 사항을 모든 여분의 LOAD_GLOBAL 두 번째 바이트 코드에 LOAD_ATTRLOAD_FAST는 않기 때문에, LOAD_FASTLOAD_GLOBAL보다 훨씬 빠르다는 것을 염두에 두어야 간단한 배열 조회, LOAD_GLOBAL은 전역 사전 (변수의 해시 계산 등이 필요함)을 조회해야합니다.

첫 번째 버전은 하나의 LOAD_GLOBAL과 하나의 LOAD_ATTR입니다. 우리는 그들의 속도를 테스트

그리고 실제로 경우 :

In [8]: %timeit test_first() 
1000000 loops, best of 3: 343 ns per loop 

In [9]: %timeit test_second() 
1000000 loops, best of 3: 542 ns per loop 

첫 번째는 거의 두 배 빠릅니다. 그러나 속도는 모두 빠르며 아마도 속도는 중요하지 않습니다. request이 로컬 변수 인 경우 속도 차이가 조금 줄어 듭니다.

두 번째 단점은 다른 단점이 있습니다. 동일한 일을 여러 번 반복합니다. 코드를 더 크고, 읽기 어렵게 만들고, 오타가 발생할 확률이 높아졌습니다. 이것은 내가 생각하기에, 그 단편의 중요한 것입니다. 성능상의 이유로 선택하는 경우 : 너무 성급한 최적화입니다.

+0

'request'가 local 인 경우 시차가 조금 줄어든다는 것에주의하십시오. 로컬 조회는 사전에 키가있는 글로벌 조회 (해시 계산 필요)와 비교하여 인덱스별로 배열에 있습니다. –

+0

@MartijnPieters 네, 이제 그 점을 지적하려고했습니다. – Bakuriu

+1

로컬 이름은 테이블의 항목이고 이미 존재하는 변수에 대한 참조이므로 메모리 사용에 영향을주지는 않습니다. –

2

아마 차이가별로 없을 것입니다. 첫 번째 해결책은 극도로 빠를 수 있습니다.

request.session.update({ 
    'v1': 1, 
    'v2': 2, 
    … 
}) 

변경의 수에 따라 새로운 정보가 이미 있는지 여부 : 솔루션 (모두 미세), 그리고 가정 request.session 외에도

당신은 고려해 볼 수 있습니다, DICT 같은입니다 dict에서.

+0

@kojiro에게 감사드립니다. – St123

관련 문제