2011-04-23 3 views
1

나는이 게시물에 의해 제기 된 문제 작업입니다 : Fast way to remove a few items from a list/queueC에서 간단한 파이썬 함수를 구현하는 것이 간단합니까?

기본적으로 내가 원하는 모든 루프 발전기를 액세스하고 배열의 요소를 제거 할 수 있어야 위해 (C로에서 루프를 구현이다 정수 증가). 나에게 무언가가 힘들 것 같지만 다른 부분은 몇 분 안에 처리 될 수 있다고한다.

고급 수준의 C (필자는 마이크로 컨트롤러 용 코드를 작성한 적이 있습니다)의 경험이 없으며 ctypes 및 기타 c-> python 용 자습서는 더 어려운 문제를 해결하는 것처럼 보입니다.

  • 이 어려운 :

    def forfilt(): 
        marked = (i for i, x in enumerate(b) if tokeep(x)) 
        shift = 0 
        for n in marked: 
         del b[n - shift] 
         shift += 1 
    

    나는이 개 질문을 해요?

  • 코드를 직접 작성하고 싶습니까? : D

이것은 실제로 나에게 다소 중요한 문제처럼 보입니다. 나는 원래의 질문에서 묻고있는 것을 빨리 할 수있는 방법을 모른다. 당신이 그 해답을 알고 있다면 그 질문은 무효라고 생각합니다.

+1

왜 C가 기본 Python 코드보다 빠르다고 생각합니까? –

+0

은 for 루프가 악명이 느리기 때문에 압축으로 해결할 수 없습니다. –

+1

Cython 또는 ShedSkin을 사용하지 않는 이유는 무엇입니까? – joaquin

답변

3

for 루프 오버 헤드를 제거하기 만하면 Cython에서 for 루프 변수의 유형을 정의하면 충분합니다 (pip install cython). for (i=0; i < L_length; ++i) 및 오버 헤드는 keep()의 함수 호출 오버 헤드가 작게되어

#cython: boundscheck=False, wraparound=False 
import cython 

@cython.locals(end=cython.Py_ssize_t, i=cython.Py_ssize_t) 
def remove_inplace_senderle2(L, keep): 
    end = 0 
    for i in range(len(L)): 
     x = L[end] = L[i] 
     if keep(x): 
      end += 1 

    del L[end:] 

for i in range(len(L))

고전 C 루프로 변환 : 여기서, A는 사이 썬 delitems.pyx remove_inplace_senderle2()에 변형이다.

참고 : 위의 함수는 순수 파이썬에서 L = filter(keep, L) (또는 listcomp)보다 느릴 수 있습니다.

더 간단한 예제 인 Cython을 컴파일하고 사용할 수있는 방법은 gcd() function을 참조하십시오.

+0

안녕하세요, 고맙습니다. 이것은 정확히 내가 묻는 질문이며 솔루션은 단순하고 파이썬 적이라고 생각합니다. D –

2

얼마나 간단합니까? 예,이 특정 함수는 입력이 배열 인 경우 내부 메모리 이동으로 작성할 수 있습니다.

n = std::remove_if(b, b+n, std::not1(tokeep)) - b; 

함수는 어레이 이외의 구조로 작동하지만 n = … - b; 배열 다르며 :

size_t for_filt(my_struct *b, size_t n) { 
    my_struct *src_pen, *dst_pen; 

    for (src_pen = dst_pen = b; 
      src_pen != b + n; 
      ++ src_pen) { 
     if (tokeep(src_pen)) { 
      memmove(dst_pen ++, src_pen, sizeof (my_struct)); 
     } 
    } 

    return dst_pen - b; /* return number of elements in resulting array */ 
} 

는 C++ 표준 라이브러리는 한 줄에 상기 기능을 감소시킨다.

2

CPython C-API에 대해 C 코드를 작성하는 것은 이러한 API를 지원하지 않고 C 코드를 작성하는 것보다 훨씬 즐겁습니다. 그러나, 그것은 주로 건물과 연결 과정이며 오히려 지루할 수있는 모든 것을 얻는 것입니다. 일단 C 확장자가 있으면, 파이썬 수준에서 적절히 노출되게하고 모든 참조 카운트가 올바른지 확인하기 위해 여전히 약간의 장난이 들기는하지만, 추가하는 것은 그리 어렵지 않습니다.

비슷한 다른 비슷한 정적 컴파일 도구는 처음에는 컴파일 된 확장 기능을 사용하기 위해 상대적으로 높은 설정 비용으로 인해 어려움을 겪었지만 이미 사용중인 경우 훨씬 쉽게 사용할 수 있습니다. 특정 질문과 관련

,하여 filter 내장에 지능형리스트 방식 (또는 Py3k 상응하는, functools.filter)이 연결 문제의 포스터를 비교함으로써이 이미 는 아래로 루핑 코드를 떨어 뜨리는 효과를 입증 C - 네이티브 루핑은 반복 반복 및 감소 함수의 주요 이점 중 하나이며 sum, any, all, mapfilter과 같은 기능을 제공합니다.

파이썬 수준 루프 오버 헤드를 제거하면 두 방법 (목록 이해 및 필터 호출)의 성능 차이가 10 % 정도 차이가납니다.

관련 문제