c# Ожидается ли такая низкая производительность WPF TextBlock?




performance (3)

Я делаю некоторые тесты, чтобы определить, могу ли я использовать WPF для нового продукта. Тем не менее, ранние результаты производительности разочаровывают. Я сделал быстрое приложение, которое использует привязку данных для отображения случайного текста внутри поля списка каждые 100 мс, и оно потребляло ~ 15% ресурсов процессора. Поэтому я сделал другое быстрое приложение, которое пропустило схему привязки данных / шаблонов данных и ничего не делает, кроме обновления 10 TextBlocks, которые находятся внутри ListBox каждые 100 мс (сам продукт не потребует обновления 100 мс, более как 500 мс, но это стресс-тест). Я до сих пор вижу ~ 5-10% загрузки процессора. Почему это так высоко? Это из-за всех мусорных строк?

Вот XAML для версии, которая не использует привязку:

<Grid>
    <ListBox x:Name="numericsListBox">
        <ListBox.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="48"/>
                <Setter Property="Width" Value="300"/>
            </Style>
        </ListBox.Resources>

        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
        <TextBlock/>
    </ListBox>
</Grid>

Вот код позади:

public partial class Window1 : Window
{
    private int _count = 0;

    public Window1()
    {
        InitializeComponent();
    }

    private void OnLoad(object sender, RoutedEventArgs e)
    {
        var t = new DispatcherTimer(TimeSpan.FromSeconds(0.1), DispatcherPriority.Normal, UpdateNumerics, Dispatcher);
        t.Start();
    }

    private void UpdateNumerics(object sender, EventArgs e)
    {
        ++_count;
        foreach (object textBlock in numericsListBox.Items)
        {
            var t = textBlock as TextBlock;
            if (t != null)
                t.Text = _count.ToString();
        }
    }
}

По данным диспетчера задач, он потребляет ~ 5-10% процессорного времени или примерно до 20% одного из ядер! Есть идеи для лучшего способа быстро отрисовать текст?

Мой компьютер: XP SP3, 2,26 ГГц Core 2 Duo, 4 ГБ оперативной памяти, интегрированная графика Intel 4500 HD. И это на порядок выше, чем оборудование, для которого мне нужно было бы разработать настоящий продукт.


Answer #1

Это медленная производительность TextBlock нормально?

Нет. Такая низкая производительность TextBlock определенно не нормальная . Мой опыт был TextBlocks гораздо быстрее, чем это.

Я провел несколько тестов, используя код, который вы разместили, оставив интервал обновления в 0,1 с и варьируя аппаратное обеспечение и количество TextBlocks. Вот что я нашел:

 10 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU:     CPU Usage "0%"
 10 TextBlocks, 2.16GHz Core 2 Duo, Software rendering:  CPU Usage 1%
100 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU:     CPU Usage 8%
100 TextBlocks, 2.16GHz Core 2 Duo, Software rendering:  CPU Usage 18%
 10 TextBlocks, 200MHz Pentium Pro, Software rendering:  CPU Usage 35%
 10 TextBlocks, 200MHz Pentium Pro, No rendering:        CPU Usage 7%

Каждый из этих тестов предполагает, что WPF примерно в 10 раз быстрее, чем показывают ваши измерения. Если ваш код так прост, как кажется, я подозреваю, что с вашим GPU или драйверами DirectX происходит что-то странное.

Обратите внимание, что для 100 тестов TextBlock мне пришлось внести три изменения: добавить 90 TextBlocks, установить ItemsPanel в WrapPanel, чтобы получить данные в столбцах, и уменьшить ширину TextBlock, чтобы все поместилось на экране.

Мой тест на 200 МГц Pentium Pro, вероятно, наиболее актуален для вашего встроенного оборудования. Если ваше приложение обновляет 10 TextBlocks каждые 0,5 с, вы можете рассчитывать на использование примерно 3% ЦП для обновления и перерисовки на 200 МГц ЦП.

Что если я хочу сделать это еще быстрее?

Использование списка связанных с данными TextBlocks очень удобно, но WPF также предоставляет механизмы более низкого уровня, которые можно использовать, когда вам нужна абсолютная максимальная производительность.

Текстовый блок WPF на самом деле содержит отформатированный документ, а не просто строку, поэтому это очень сложная структура данных. Довольно просто написать свой собственный TrivialTextBlock управления TrivialTextBlock который имеет строковый параметр, и просто рисует его, используя унаследованные свойства TextElement (такие как FontSize, FontWeight и т. Д.). Это обычно не делается, потому что TextBlock достаточно быстр для почти всех целей.

Другое соображение заключается в том, что каждый раз, когда вы изменяете текст в TextBlock, WPF пересчитывает макет. В отличие от старых технологий, содержимое текстового блока WPF может очень легко изменить макет вашего пользовательского интерфейса. Таким образом, текст должен быть переформатирован и переформатирован каждый раз, когда вы меняете его. Создание вышеупомянутого TrivialTextBlock управления TrivialTextBlock может ускорить это, установив размер TrivialTextBlock управления и, таким образом, избегая проходов макета.

Третье соображение заключается в том, что форматировщик текста WPF имеет расширенные функции типографики, поддерживающие такие вещи, как кернинг, двунаправленный текст, лигатуры, функции юникода, настраиваемые веса шрифтов и т. Д. Чтобы получить абсолютную максимальную производительность в WPF, вы можете полностью обойти форматировщик текста и нарисовать Текст как серия изображений. Для этого требуется около 20 строк XAML и около 40 строк кода C #.

Все эти оптимизации возможны, но в вашем случае я бы не стал беспокоиться о них: сделать это, чтобы сэкономить всего лишь 3% загрузки ЦП, вероятно, не стоит.


Answer #2

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

Моя команда выбрала WPF для проекта, ориентированного на процессорную платформу Atom, потому что интегрированная графика GMA 500 требовала рендеринга WPF уровня 2. Однако по какой-то причине производительность GMA 500 очень низкая, и мы отключили аппаратный рендеринг для повышения производительности. Даже тогда платформа Atom недостаточно мощна для разумной производительности. Я не советую использовать WPF, если нетбуки или что-либо с Intel Atom является частью вашей клиентской базы.

Вот ссылка на мой открытый вопрос о производительности WPF на GMA 500.

Как предполагает Роб Перкинс, вам может быть лучше с Silverlight 4 для лучшей производительности.

Удачи!


Answer #3

Что касается производительности, в WPF можно многое сделать неправильно. Многие люди подходят к нему, как к приложению win form, веб-странице html или к какой-то гибридной атаке при разработке приложения, и из-за этого существует множество плохих оценок WPF.

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

http://msdn.microsoft.com/en-us/magazine/dd483292.aspx

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

Чтобы провести честный тест, я бы написал пример приложения, которое будет иметь дело с образцом данных, с которыми вы собираетесь работать, и затем протестируете производительность этого кода. Существует большое количество оптимизаций, которые можно применить, чтобы заставить приложение WPF кричать и использовать меньше ресурсов ЦП, но все они зависят от вашего приложения и от того, как оно представляет ваши данные.

Надеюсь это поможет.





textblock