我正在编写一种测量采样正弦波频率的方法。它需要一个稍大的1D阵列(10 ^ 3到10 ^ 4个样本数量级)并返回double
。在方法体内也会调用辅助方法,以检查波是否过零。这是我写的一个例子:
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-4毫秒内运行。
但是,我对在推荐范围之外冒险感到不舒服。有没有办法在安全的环境中达到相同的速度?如果没有,它是否会破坏使用C#的目的?我真的应该将C#用于这些信号处理应用和科学实现吗?
这只是我正在编写的许多DSP方法中的一种,它采用大量样本作为输入。但是这个让我意识到有一个问题,因为当我测试这个方法时,我意外地输入了48000个样本而不是4800个,并且返回一个值需要20秒。
谢谢。
更新:我尝试在之前的代码段Take(2)
之后添加Skip(i - 1)
。这使它降至90-100毫秒,但问题仍然存在。
答案 0 :(得分: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]) {
可能会为发布版本内联这样一个简单的方法,使其尽可能快。