有没有更快的方法在安全模式下遍历数组
Is there a faster way to loop over an array in safe mode
我正在编写一种方法来测量采样正弦波的频率。它需要一个有点大的一维数组(10^3 到 10^4 个样本数量级)和 returns a 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 秒才能 return 一个值。
谢谢。
更新: 我尝试在前一个片段中的 Skip(i - 1)
之后添加 Take(2)
。这将它降低到 90-100 毫秒,但问题仍然存在。
您不需要将数组元素的副本传递给 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]) {
这种简单的方法可能会内联到发布版本中,使其尽可能快。
我正在编写一种方法来测量采样正弦波的频率。它需要一个有点大的一维数组(10^3 到 10^4 个样本数量级)和 returns a 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 秒才能 return 一个值。
谢谢。
更新: 我尝试在前一个片段中的 Skip(i - 1)
之后添加 Take(2)
。这将它降低到 90-100 毫秒,但问题仍然存在。
您不需要将数组元素的副本传递给 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]) {
这种简单的方法可能会内联到发布版本中,使其尽可能快。