2012-04-20 2 views
0

Мне нужно отобразить набор сигналов. Каждый сигнал определяется миллионами выборок. Просто обработка коллекции (для преобразования выборок в точки в соответствии с размером растрового изображения) образцов занимает значительное количество времени (особенно во время прокрутки).Сигнал рисования с большим количеством образцов

Итак, я реализовал какую-то понижающую дискретизацию. Я просто пропущу некоторые моменты: каждый второй, каждый третий, каждую 50-ю точку в зависимости от характеристик сигнала. Это значительно увеличивает скорость, но значительно искажает форму сигнала.

Есть ли более разумные подходы?

+1

Вы объяснили некоторые и рассказали некоторые, но мы до сих пор не знаем, что такое эти сигналы и что вы действительно пытаетесь сделать. – SimpleVar

+0

Просто примечание: если вы говорите о * миллионах * данных, то видишь визуализацию в реальном времени, * не используйте .NET *. Например, для Python существует множество хороших библиотек. – Tigran

+0

Посмотрите на другой вопрос: [График огромных объемов данных] (http://stackoverflow.com/questions/4817960/charting-massive-amounts-of-data) – Justin

ответ

2

У нас была аналогичная проблема в недавнем приложении. Наша визуализация (простой линейный график) стала слишком захламленной при увеличении масштаба, чтобы увидеть всю полноту данных (около 7 дней образцов с образцом, взятым каждые 6 секунд больше или меньше), поэтому выборка на самом деле была способ пойти , Если бы мы этого не сделали, масштабирование не имело бы большого значения, поскольку все, что вы могли видеть, было просто большим пятном линий, размазанных по экрану.

Все зависит от того, как вы собираетесь внедрять сэмплирование. Есть два (простых) подхода: down-sample в тот момент, когда вы получаете образец или нисходящий образец во время отображения. Что действительно дает огромный прирост производительности в обоих случаях, это правильный выбор источников данных.

Предположим, у вас 7 миллионов образцов, и ваше окно просмотра просто интересуется последним миллионом очков. Если ваша реализация зависит от IEnumerable, это означает, что IEnumerable будет иметь MoveNext 6 миллионов раз перед фактическим запуском. Однако, если вы используете что-то, который оптимизирован для случайного чтения (список приходит на ум), вы можете реализовать свой собственный нумератор для этого, более или менее, как это:

public IEnumerator<T> GetEnumerator(int start, int count, int skip) 
{ 
    // assume we have a field in the class which contains the data as a List<T>, named _data 
    for(int i = start;i<count && i < _data.Count;i+=skip) 
    { 
     yield return _data[i]; 
    } 
} 

Очевидно, что это очень наивно но вы можете делать все, что захотите, внутри цикла for (используйте алгоритм, основанный на окружающих выборках, в среднем?). Однако этот подход позволит сгладить любые экстремальные всплески в вашем сигнале, поэтому будьте осторожны.

Другим подходом было бы создание некоторых обобщенных версий вашего набора данных для разных диапазонов, которые обновляются каждый раз, когда вы получаете новый сигнал. Обычно вам не нужно обновлять полный набор данных; просто обновление конца вашего набора, вероятно, достаточно хорошо. Это позволяет выполнять немного более совершенную обработку ваших данных, но это будет стоить больше памяти. Вам придется кэшировать отдельные «слои» деталей в вашем приложении.

Однако, прочитав ваше (краткое) объяснение, я думаю, что оптимизация времени отображения может быть достаточно хорошей. Если вы обобщите, вы всегда получите искажение сигнала. Вы всегда теряете данные. Это зависит от выбранного вами алгоритма, как это будет происходить, и насколько это заметно.

1

Вам нужен лучший алгоритм выборки, также вы можете использовать функции параллельной обработки C#. См. Task Parallel Library

Смежные вопросы