2016-10-28 8 views
0

샘플링 된 사인파의 주파수를 측정하는 방법을 쓰고 있습니다. 다소 큰 1D 배열 (10^3에서 10^4 샘플의 크기 순서)을 취해 double을 반환합니다. 도우미 메서드는 웨이브가 0을 교차하는지 여부를 확인하는 메서드 본문 내에서 호출됩니다. 다음은 필자가 작성한 예제입니다.안전 모드에서 배열을 루프하는 더 빠른 방법이 있습니까

public static double Hertz(float[] v, int n) { 
    int nZCros = 0 
    for (int i = 1; i < n; i++) { 
     if (IsZeroCrossing(v.Skip(i - 1).ToArray())) { 
      ++nZCros; 
     } 
    } 
    return (double)nZCros/2.0; 
} 
private static bool IsZeroCrossing(float[] v) { 
    bool cross; 
    //checks if the first two elements of the array are opposite sign or not 
    return cross; 
} 

제 문제는 실행하는 데 200-300 밀리 초가 걸리는 것입니다. 그래서 저는 unsafe과 포인터를 사용해보기로했습니다.

public unsafe static double Hertz(float* v, int n) { 
    int nZCros = 0 
    for (int i = 1; i < n; i++) { 
     if (IsZeroCrossing(&v[i - 1])) { 
      ++nZCros; 
     } 
    } 
    return (double)nZCros/2.0; 
} 
private unsafe static bool IsZeroCrossing(float* v) { 
    bool cross; 
    //checks if the first two elements of the array are opposite sign or not 
    return cross; 
} 

2 ~ 4ms로 실행됩니다.

그러나 나는 권장 범위를 벗어나지 않는 편이 낫다고 생각합니다. 안전한 상황에서 동일한 속도를 얻을 수있는 방법이 있습니까? 그리고 그렇지 않은 경우, C#을 사용하는 목적을 무효로합니까? 이러한 종류의 신호 처리 응용 프로그램과 과학적 구현을 ​​위해 실제로 C#을 사용해야합니까?

이것은 많은 샘플 배열을 입력으로 사용하는 필자가 쓰는 많은 DSP 방법 중 하나 일뿐입니다. 하지만이 방법을 테스트 할 때 우연히 4800 대신 4800 샘플을 넣었 기 때문에 문제가 있다는 것을 깨닫게되었습니다. 값을 반환하는 데 20 초가 걸렸습니다.

감사합니다.

업데이트 : 이전 스 니펫에서 Skip(i - 1) 이후에 Take(2)을 추가하려고 시도했습니다. 이것은 90-100 밀리 초로 내려 갔지만 문제는 여전히 남아 있습니다.

+1

나는 여기에 차이를 만들어내는 것이 안전 대 안전하지 않은 결정이 아니라고 강력하게 의심합니다. 그것은'v.Skip (i - 1) .ToArray()'입니다. – adv12

+0

나는 그것을 의심했다. 그래서 LINQ가 범인입니까? – skwear

+0

나는 LINQ의 오용이 범인이라고 말할 것이다. 확실히, 모든 반복에서 열거 형을 배열로 변환하는 것은 오프셋이있는 배열을 전달하는 것보다 비용이 많이 듭니다. – adv12

답변

3

배열 요소의 복사본을 IsZeroCrossing()으로 전달할 필요가 없습니다.

private static bool IsZeroCrossing(float elem1, float elem2) 
{ 
    return elem1*elem2 < 0.0f; // Quick way to check if signs differ. 
} 

그래서 같이 호출 :

if (IsZeroCrossing(v[i-1], v[i]) { 

그것은 같은 간단한 방법은 릴리스 빌드를 위해 인라인 될 가능성이 있습니다

대신

, 당신이 관심있는 두 요소를 전달 가능한 한 빨리 만듭니다.

+0

+1 좋은 답변이지만, 내가 언급 한 더 큰 문제의 핵심에 도달하지 못합니다. 나는 오프셋의 배열을 나머지 두 요소 만 가져가는 것이 아니라 다른 두 가지 요소를 취하는 다른 방법을 가지고있다. – skwear

+3

@skwear, 그런 경우에는 주석에 제안 된대로 배열과 오프셋을 전달하십시오. – adv12

+0

감사합니다. @ adv12. 나는 꽤 많은 리팩토링을해야한다. – skwear