샘플링 된 사인파의 주파수를 측정하는 방법을 쓰고 있습니다. 다소 큰 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 밀리 초로 내려 갔지만 문제는 여전히 남아 있습니다.
나는 여기에 차이를 만들어내는 것이 안전 대 안전하지 않은 결정이 아니라고 강력하게 의심합니다. 그것은'v.Skip (i - 1) .ToArray()'입니다. – adv12
나는 그것을 의심했다. 그래서 LINQ가 범인입니까? – skwear
나는 LINQ의 오용이 범인이라고 말할 것이다. 확실히, 모든 반복에서 열거 형을 배열로 변환하는 것은 오프셋이있는 배열을 전달하는 것보다 비용이 많이 듭니다. – adv12