Может ли WPF отображать линейный путь с 300 000 точек в среде, чувствительной к производительности?

Простой линейный график XY: ось X будет представлять полный диапазон возможных процентов рейтинга, от 0% на одном конце до 100% на другом. В частности, значение X будет представлять собой отсечение нашего рейтинга или минимальный рейтинг, который может иметь транзакция, прежде чем она станет неприемлемой. На оси Y будут отображаться значения от 0 до общего количества выполненных транзакций. Значение Y будет представлять собой общее количество транзакций, рейтинг которых выше текущего значения X (или больше или равен текущему значению X, я еще не решил). При первом построении этого графика транзакций не будет, поэтому график будет начинаться с «y=0x».

Допустим, прошла первая транзакция с рейтингом 40%. Рейтинг транзакции указывает на то, что эта транзакция приемлема, если пороговое значение нашего рейтинга составляет менее 40%. (... или меньше или равно 40%. Опять же, я еще не решил).

Во-первых, масштаб оси Y изменится, чтобы показать диапазон от 0 до 1 (поскольку 1 — это общее количество транзакций). Затем строка будет изменена, чтобы указать, что 0 транзакций допустимы при x=40 или более, и что 1 транзакция приемлема при x=40 или менее. Этого легко добиться в WPF, просто добавив две точки к пути линии — одну в (40,0) и другую в (40,1) — а затем переместив левую конечную точку линии в (0,1). Правая конечная точка линии останется на (100,0). Затем этот процесс можно повторить для второй транзакции и так далее.

Проблема в том, что мы будем иметь дело с шестизначным количеством транзакций. и я хочу убедиться, что я использую возможности аппаратного ускорения векторного рисования WPF в полной мере, чтобы гарантировать, что график не будет отставать или зависать от остальной части программы, когда она пытается отобразить 300 000 точек на одной линии пути. Или WPF должен уметь обрабатывать такие числа в мгновение ока? Мне нужно найти способ реализовать этот график, не замедляя работу приложения. Я верю, что платформа векторного рисования WPF предоставит решение, но я недостаточно знаю, как использовать WPF, чтобы быть уверенным, что я получаю максимальную отдачу от возможностей высокопроизводительного рендеринга WPF.


person Giffyguy    schedule 11.06.2009    source источник
comment
Дайте мне знать, как это работает для вас.   -  person    schedule 26.09.2009
comment
Это старый вопрос, но мне интересно, нашли ли вы решение своей проблемы? Потратив довольно много времени на эксперименты с высокопроизводительным рендерингом в WPF, я обнаружил, что наибольшей производительности можно добиться, вообще не используя примитивы WPF, а используя WriteableBitmap API. Это или Direct2D. Мне было бы интересно услышать ваш опыт в любом случае. С наилучшими пожеланиями,   -  person Dr. Andrew Burnett-Thompson    schedule 04.01.2012


Ответы (6)


Я только что наткнулся на этот пост и сам создаю элемент управления линейным графиком, который должен быть очень производительным, поскольку мы обновляем точки на наших линиях в режиме реального времени.

Если вам нужна производительность и количество визуальных элементов... Я сомневаюсь, что вы найдете более эффективный подход, чем программирование непосредственно на визуальном уровне WPF (ссылки: 1, 2). Мои первые результаты от использования этого подхода были очень положительными.

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

То есть, если все, что вам нужно обновить, это точка на линии, то обновление точки заставит обновить линию Visual, но не заставит обновить остальную часть графика (оси, линии сетки,...). , так как инструкции по рисованию для них сохранены и будут использоваться повторно (поскольку они не обновляются).

Глава 14 в Pro WPF в C# 2008 Мэтью Макдональда содержит отличный раздел (под названием «Визуальные элементы»), посвященный программированию на визуальном уровне WPF. Глава 2 Развитие управления WPF< /em> также есть раздел на стр. 13, где он обсуждает, как подход DrawingVisual был бы идеальным для компонента диаграммы. Наконец, Чарльз Петцольд написал журнал MSDN статья, в которой лучшим общим решением для точечной диаграммы был подход DrawingVisual.

(Теперь я знаю, что в вашем вопросе упоминалось, что оси также будут обновляться... и поэтому мой ответ действительно относится к общему случаю... но я все же думаю, что этот подход будет наиболее эффективным... поскольку обновятся только те вещи, которые нуждаются в обновлении...)

person cplotts    schedule 25.09.2009
comment
Это имеет смысл и является идеальным описанием подхода, который я сейчас пробую. График, который я строил еще в июне, был разработан с использованием предложения Пола Беттса. Но совсем недавно я строил еще один подобный график, и это решение, похоже, отлично работает. Все, что я делаю, это обновляю только наименьшее количество объектов (в моем IValueConverter), а визуальный слой WPF, кажется, может обрабатывать остальные без инцидентов. - person Giffyguy; 26.09.2009
comment
@Giffyguy: Вы все еще отображаете 300 000 точек данных или уменьшили их? Все эти точки данных видны на одном экране или вам нужно прокручивать? - person ; 27.09.2009
comment
Если этот подход вам не подходит, попробуйте использовать элемент управления Image с динамически генерируемым DrawingImage. Как я упоминал в stackoverflow.com/questions/952657/, Паван Подила упоминает, что этот подход довольно хорошо масштабируется... и может помочь вам, если вам не нужно взаимодействовать с точками ... и даже тогда вы можете поумничать в этом. Дополнительную информацию см. на стр. 25 его книги WPF Control Development Unleashed. - person cplotts; 17.10.2009

Если вы хотите, чтобы это было быстро, лучший способ — получить от Control и реализовать OnRender — обычно в этом нет необходимости, но для вашего приложения это может быть.

Кроме того, давайте сделаем шаг назад — экран, на который вы выполняете рендеринг, определенно не имеет 300 тыс. пикселей в поперечнике; прежде чем перейти к рендерингу, уменьшите буфер, усредняя n узлов в один, пока не получите что-то близкое к разрешению реального устройства, затем нарисуйте это на экране.

person Ana Betts    schedule 11.06.2009
comment
OnRender может быть более производительным, чем некоторые подходы ... но будьте осторожны, пытаясь управлять WPF в режиме немедленного режима (что может побудить вас сделать переопределение OnRender) ... WPF - это система композиции с сохраненным режимом. Я сам был укушен, делая именно это. - person cplotts; 25.09.2009
comment
+1 за идею минимизировать точки на линии в зависимости от разрешения устройства. Очень умно. - person cplotts; 25.09.2009
comment
Уменьшение количества точек — это больше хак, чем что-либо еще с WPF, поскольку хост может быть перемасштабирован (увеличен/уменьшен), а визуальные элементы не могут узнать свой истинный размер на экране. - person ; 26.09.2009
comment
Германн делает отличное замечание. В сочетании с тем фактом, что масштаб моего графика полностью зависит от точности набора точек, я чувствую, что мне нужно убедиться, что все точки сохранены, независимо от окончательного разрешения. - person Giffyguy; 26.09.2009
comment
Если вы увеличиваете масштаб, то многие точки оказываются за кадром; Первое, чему вас учат в программировании на GPU, это то, что самый быстрый объект — это тот, который вы не рисуете. Если вы увеличили масштаб, вы должны удалить все точки в буфере, которые не находятся в видимом диапазоне, и вам все еще, возможно, придется уменьшить его. Я не говорю, что вы должны уничтожить исходный буфер, просто сделайте уменьшенную копию, прежде чем передавать ее в представление. - person Ana Betts; 27.09.2009
comment
@Paul Bettts: WPF делает все это за вас автоматически. - person ; 27.09.2009
comment
@Hermann Мне придется изучить этот визуальный слой, я определенно мог бы делать слишком много работы вручную - спасибо за совет! - person Ana Betts; 28.09.2009
comment
WPF на самом деле довольно умно подходит к тому, что отображать, когда речь идет о визуальных элементах. Я визуализировал около 100 000 визуальных элементов (прямоугольники, линии и текст) на диаграмме, и производительность была потрясающей. Вы даже можете преобразовать их, и процессор просто спит, потому что все это работает на видеокарте. Однако известно, что у WPF есть проблемы со строками. Я надеюсь, что они исправят это в будущем. - person ; 28.09.2009
comment
cplotts связаны с wpftutorial.net/DrawOnPhysicalDevicePixels.html в моем вопросе, который показывает вам, как получить окончательное разрешение, в котором он отображается. Может быть полезно. - person ; 17.10.2009

Я не знаю ответа, но кодирование быстрого теста не должно занять намного больше времени, чем для вас, чтобы опубликовать. Кроме того, см. эту тему для аналогичное обсуждение.

person PeterAllenWebb    schedule 11.06.2009

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

SimulationSample генерирует много данных, так что это хорошее место для начала.

person Wilka    schedule 11.06.2009
comment
Вы знаете, как реализован WPF DynamicDataDisplay? Использует ли он визуальные эффекты? - person ; 26.09.2009
comment
Интересно, безусловно. Но пока это звучит так, как будто это больше сосредоточено на динамических данных, чем на динамическом отображении. Я сомневаюсь, что будет много пользы для пользовательского визуального вывода, разработанного создателем данных. - person Giffyguy; 26.09.2009
comment
У них есть разные типы диаграмм для разных нужд. Некоторые люди работают над дополнением DirectX Line Graph, которое должно быть быстрым. У них есть диаграмма, которая использует DrawingContext напрямую, что на данный момент является самым быстрым. Все, что использует ретентивную систему, будет слишком медленным для 300 000 различных точек данных (если вы хотите отобразить их все). - person Adam Mills; 04.07.2011

Если вы не используете .NET 3.5 SP1, просто не используйте эффекты шейдера. В противном случае вам, как разработчику WPF, не так много нужно делать. чтобы убедиться, что он использует аппаратное ускорение.

person AgileJon    schedule 11.06.2009
comment
Хорошо. Но не слишком ли велика для него эта нагрузка? Я имею в виду, что рендеринг модели с таким количеством точек — это немного больше, чем я когда-либо видел в своем (хотя и ограниченном) опыте моделирования и рендеринга. - person Giffyguy; 11.06.2009
comment
Я думаю, что я спрашиваю: должен ли я использовать линейный путь и добавлять точки по мере прохождения транзакций, или мне следует искать еще одно решение? - person Giffyguy; 11.06.2009
comment
Вы имеете в виду растровые эффекты? Вместо шейдерных эффектов? - person cplotts; 25.09.2009
comment
Хм... Я даже не рассматривал растровые эффекты. Когда-то, когда я был разработчиком C++ 6.0, я был поглощен работой с растровыми изображениями. Я люблю говорить, что освоил использование MFC и GDI. Но возвращение к растровым изображениям кажется гигантским шагом назад, когда я пытаюсь изучить способ WPF, а не GDI. И поскольку WPF обеспечивает такую ​​простоту с классами Visual и Shape, я думаю, что могу ограничить себя в том, сколько боли я готов терпеть, чтобы ускорить это. Попытка отобразить этот график в виде растрового изображения звучит НАМНОГО больше хлопот, чем оно того стоит. - person Giffyguy; 26.09.2009
comment
Растровые эффекты (до .NET 3.5 SP1) были источником проблем с производительностью ... поскольку .NET 3.5 SP1 преобразует растровые эффекты в фактические эффекты графического процессора (в большинстве случаев), теперь это не проблема ... но только тогда Было предложено 2 растровых эффекта, запеченных в эффектах графического процессора (тень и размытие). - person cplotts; 26.09.2009
comment
Я не предлагал использовать растровые эффекты, как и AgileJon (в моем понимании). Он просто указал, что они могут быть источником проблем с производительностью ... поскольку иногда они могут вызывать программный рендеринг. - person cplotts; 27.09.2009
comment
Моя ошибка. Я думаю, что я не знаком с этим использованием терминологии. Когда я слышу слово растровое изображение, я предполагаю, что вы имеете в виду bitblt() и alphablend() и любую другую старомодную форму высокоскоростных аппаратно-ускоренных манипуляций с растровыми изображениями. Но теперь, когда я думаю об этом, растровые эффекты — это четкая ссылка на эффект, а не на метод рендеринга. Я так озабочен рендерингом, что совершенно забыл рассматривать эффекты как фактор производительности. - person Giffyguy; 27.09.2009

ИМХО, Пол, похоже, на правильном пути, проверьте Помимо разделов, посвященных сглаживанию карты, в некоторых примерах для наборов данных используются результаты выборов во Флориде в 2000 году (~9 миллионов голосов, 18+ миллионов человек).

В соответствии с потоком от AgileJon, в некоторой степени, я бы просто вручную создал растровое изображение, если бы не было доступной прямой техники для лучшего определения вашего набора данных. Я визуализирую диаграммы разброса, которые легко составляют 16 000 000 (16 миллионов+) в секундах, полная 32-битная палитра ARGB.

Вы, кажется, заметили: «Но возвращение к растровым изображениям кажется гигантским шагом назад», я бы не стал так быстро говорить, что вселенная ограничена физическими пределами.

Другой пост я отослал к этой статье codeproject, в которой 3D сюжеты + анимация и т.д...

person RandomNickName42    schedule 26.02.2010