Я пишу метод измерения частоты выборочной синусоидальной волны. Он занимает несколько большую 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 мс, но вопрос все еще стоит.
Я сильно подозреваю, что это не безопасное решение против небезопасности, которое меняет здесь; это 'v.Skip (i - 1) .ToArray()'. – adv12
Я подозревал это. Итак, LINQ является виновником? – skwear
Я бы сказал, что злоупотребление LINQ является виновником. Определенно, преобразование перечислимого в массив на каждой итерации будет намного дороже, чем просто передать массив со смещением. – adv12