2011-10-19 3 views
4

내 기능을 구성하는 두 가지 방법을 살펴보십시오.다른 함수 정의 내부의 함수 정의 -slow?

class myClass: 
    def _myFunc(self): 
     pass 

    def myFunc2(self): 
     self._myFunc() 

class myClass: 
    def myFunc2(self): 
     def myFunc(): 
      pass 

     myFunc() 

두 번째 옵션의 속도가 느려 집니까? 필자는 myFunc2에서 myFunc를 호출하기 만하면됩니다. 따라서 모듈 문서에서 숨기고 싶습니다. 밑줄을 사용할 수는 있지만 함수 내부에 있어야한다고 생각했습니다. 반면에 myFunc2를 초당 수백 번 호출해야 할 수도 있으므로 myFunc2를 호출 할 때 myFunc를 "재정의"할 때마다 느려질 수 있습니다 ... 좋은 추측입니까?

+0

내가 생각할 수있는 유일한 차이점은 전역 변수와 함께 할 수있는 뭔가이며, 모든 일이 클래스에 싸여 있기 때문에 문제가되지 않습니다 그 당 574 MS. – katrielalex

답변

3

번째 변형의 로컬 함수는 또 다시 컴파일 될 것이다 - 이것은 한번 컴파일 전체 파일과 함께 그 본문은 코드 객체에 저장됩니다. 외부 함수의 실행 중에 발생하는 유일한 일은 코드 객체가 로컬 함수 이름 myFunc에 바인딩 된 새 함수 객체로 래핑된다는 것입니다.

myFunc()이 기본 매개 변수를 사용하는 경우 두 변종간에 차이가있을 수 있습니다. 그들의 정의는 두 번째 변형에서 계속해서 반복 실행되어 성능이 저하 될 수 있습니다.

과장된 예 : myClass2.myFunc2() 실행하는 초 걸리는 동안 상기 미치게 코드

from time import sleep 

class MyClass: 
    def _my_func(self, x=sleep(1)): 
     pass 
    def my_func2(self): 
     self._my_func() 

class MyClass2: 
    def my_func2(self): 
     def my_func(x=sleep(1)): 
      pass 
     my_func() 

myClass.myFunc2() 즉시 반환한다.

+0

'myClass2.myFunc2()'가 1 초가 걸리는 이유를 모르지만'myClass.myFunc2()'는 즉시 반환됩니다. myFunc()가 기본 매개 변수를 취하는 경우 두 번째 변형에서 정의가 계속 반복 실행되는 이유는 무엇입니까? – Alcott

+0

@Alcott : 기본 인수는 함수 정의가 실행될 때 평가됩니다.두 번째 변형은'my_func2()'안에 있기 때문에 함수 정의를 다시 실행합니다. 첫 번째 변형은 함수 정의를 한 번만 실행합니다. –

+0

그러면 myClass.myFunc2()는 실행하는데 1 초가 걸릴 것이고 myClass2.myFunc2()는 2 초가 걸릴 것이라고 생각하십니까? – Alcott

6

어떠한 뚜렷한 차이가 없음

# version 1 
In [2]: %timeit c1.myFunc2() 
1000000 loops, best of 3: 461 ns per loop 

# version 2 
In [3]: %timeit c2.myFunc2() 
1000000 loops, best of 3: 464 ns per loop 
2

점으로 구분 된 조회 (특성 바인딩)는 항상 중첩 된 범위 조회보다 오래 걸립니다. 전자는 일련의 사전 검색과 새 객체 생성 (바인딩 된 메소드 또는 바인딩되지 않은 메소드)을 포함합니다. 후자는 셀 변수를 사용하며 배열 조회를 사용하여 구현됩니다.

0

효과가 없다고 주장하는 다른 답변에도 불구하고 확인해야한다고 생각했습니다. 외부에서 함수를 정의 할 때 매우 명확한 이점을 발견했습니다.

import random 
def ff1(i): 
    r1 = random.random() 
    r2 = random.random() 
    if r1 < 0.5: 
     return i*r2 
    else: 
     return i/r2 

def f1(i): 
    return ff1(i) 

def f2(i): 
    def ff2(i): 
     r1 = random.random() 
     r2 = random.random() 
     if r1 < 0.5: 
      return i*r2 
     else: 
      return i/r2 
    return ff2(i) 
%%timeit -r 10 -n 10 
x = 0.5 
for i in xrange(10000): 
    x = f1(x) 

10 루프, 10의 최고 : 루프 당 4.2 밀리

%%timeit -r 10 -n 10 
x = 0.5 
for i in xrange(10000): 
    x = f2(x) 

10 루프, 10의 최고 : 루프 당 5.33 밀리

%%timeit -r 1 -n 1 
x = 0.5 
for i in xrange(1000000): 
    x = f1(x) 

1 개 루프, 최고의 루프 당 1 : 438msec

%%timeit -r 1 -n 1 
x = 0.5 
for i in xrange(1000000): 
    x = f2(x) 
의 가장개

1 루프 : 루프