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

Я делаю некоторое сравнительное тестирование, чтобы определить, могу ли я использовать 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, Core 2 Duo на 2,26 ГГц, 4 ГБ RAM, Intel 4500 HD интегрировал графику. И это - порядок величины, более раскормленный, чем аппаратные средства, для которых я должен был бы разработать в реальном продукте.

18
задан Ben Schoepke 17 March 2010 в 19:39
поделиться

2 ответа

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

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

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

 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 раз быстрее, чем показывают ваши измерения. Если ваш код такой простой, как кажется, я подозреваю, что с вашим графическим процессором или драйверами DirectX происходит что-то странное.

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

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

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

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

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

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

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

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

41
ответ дан 30 November 2019 в 06:35
поделиться

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

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

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

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

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

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

4
ответ дан 30 November 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: