2017-10-04 1 views
3

오랫동안 C++ 개발자입니다. 파이썬에서 알고리즘 작업을 시작했습니다. 나는 현재 파이썬에서 효율적으로 프로그래밍하는 방법에 대한 느낌을 얻기 위해 코드를 프로파일 링하고있다. 특히 전문적인 설명을 얻게되어 매우 기쁘다. 파이썬 요소 액세스 성능

나는 레이 - 삼각형의 교차점이 래퍼 함수를 ​​쓴 :

def rayIntersectsTriangle(origin , direction , meshData , poly , worldCoordinateVertices): 
    return mathutils.geometry.intersect_ray_tri(worldCoordinateVertices[ meshData.loops[ poly.loop_start ].vertex_index ], 
               worldCoordinateVertices[ meshData.loops[ poly.loop_start + 1 ].vertex_index ], 
               worldCoordinateVertices[ meshData.loops[ poly.loop_start + 2 ].vertex_index ], 
               direction , origin) != None 

이 기능을 시간을 많이 실행되는 코드를 (cprofile 명령을 사용하여) 프로파일 나는 다음과 같은 결과가 :

ncalls tottime percall cumtime percall filename:lineno(function) 
15694126 22.314 0.000 25.812 0.000 ****.py:176(rayIntersectsPoly) 
[...] 
15694126 3.497 0.000 3.497 0.000 {built-in method mathutils.geometry.intersect_ray_tri} 

어떻게이 래퍼가 많은 오버 헤드를 추가합니까? 여기서 실제로 볼 수있는 유일한 것은 배열 요소 액세스입니다. C + +에서 오는 이것은 내게 정말로 혼란 스럽습니다 : D

이것에 대한 도움은 매우 감사하겠습니다. 알고리즘을 가능한 빨리 얻고 싶습니다.

미리 감사드립니다. 건배!

+0

https://wiki.python.org/moin/TimeComplexity –

+0

... 및 btw를 참조하십시오. 수학 중심 워크로드에서 런타임 성능을 최우선으로 생각하면 파이썬이 당신을위한 언어가 아닐 수도 있습니다. [Julia] (https://julialang.org/) 또는 [Go] (https://golang.org/)를 제안 할 수 있습니까? (벤치 마크는 Julia의 페이지 커버 다). –

+0

굉장합니다. 자원에 감사드립니다. 현재 블렌더 용 플러그인을 사용하고 있으므로 파이썬에 대한 대안이 없습니다. – Marcel

답변

5

mathutils.geometry.intersect_ray_tri()이 이므로 시간이 크게 보입니다. 이 메서드는 확장 기능에서 구현되며 기본 속도로 실행됩니다.

방법에 대한

파이썬 시간은 간다 :

  • 가 (이은에 완료
  • 글로벌 이름 조회 (만 시간이 걸리는 하나의 표현 비교적 큰 비율로) 새로운 기능 프레임 만들기 맵핑, 로컬 명은 배열을 사용). mathutils.geometrymathutils.geometry.intersect_ray_tripoly.loop_start
  • 인덱싱, 그래서 worldCoordinateVertices[ ... ] 같은
  • 속성 조회.

당신은 지역 이름이나 기본 매개 변수에서 이러한 일부의 결과를 캐싱하여 조금 더 빨리 만들 수 :

def rayIntersectsTriangle(
     origin, direction, meshData, poly, worldCoordinateVertices 
     _intersect_ray_tri=mathutils.geometry.intersect_ray_tri): 
    loop_start = poly.loop_start 
    meshData_loops = meshData.loops 
    return _intersect_ray_tri(
     worldCoordinateVertices[meshData_loops[loop_start].vertex_index], 
     worldCoordinateVertices[meshData_loops[loop_start + 1].vertex_index], 
     worldCoordinateVertices[meshData_loops[loop_start + 2].vertex_index], 
     direction, origin) is not None 

나는 또한 is not None을 사용; 그것은 None 싱글 톤에 대한 테스트에 권장되는 포인터 연산입니다.

약 8 개의 속성 조회가 단지 2 개가되고 mathutils의 전역 이름 조회가 제거됩니다.

여전히 미세 최적화입니다. 실제로 영향을 미친 경우에만 수행합니다 (예 : 메소드가 코드에서 많이 호출 됨). 이 문제가 실제로 병목 현상이라면 Cython을이 코드를 네이티브 속도로 작동 할 수있는 컴파일 된 확장으로 변환하는 쉬운 경로로 사용해보십시오.

+0

와우, 정말 고마워요. 얼마나 상세하고 빠른 대답. 이것은 분명히 나에게 많은 통찰력을 준다. – Marcel