У нас есть приложение, в котором есть одно или несколько окон текстовой консоли, которые по сути представляют последовательные порты (ввод и вывод текста, символ за символом). Эти окна превратились в серьезную проблему производительности в том виде, в каком они сейчас кодируются ... нам удается проводить в них очень значительную часть времени.
Текущий код структурирован так, что окно живет своей маленькой жизнью, а основной поток приложения управляет им через вызовы «SendMessage ()». Эта передача сообщений, кажется, является причиной невероятных накладных расходов. По сути, обход ОС кажется неправильным.
Обратите внимание, что мы рисуем текстовые линии целиком, где это необходимо, так что простая оптимизация уже выполнена.
Я не эксперт в кодировании Windows, поэтому мне нужно спросить сообщество, есть ли какая-то другая архитектура для отображения текста в окне, кроме отправки таких сообщений? Вроде довольно тяжеловес.
Обратите внимание, что это на C++ или обычном C, поскольку основное приложение - это переносимая программа на C / C++ / некоторых других языках, которая также работает в Linux и Solaris.
Мы провели еще несколько исследований, похоже, что половина накладных расходов связана с подготовкой и отправкой каждого сообщения с помощью SendMessage, а другая половина - это фактическое рисование экрана. SendMessage выполняется между функциями в одном файле ...
Итак, я полагаю, что все приведенные ниже советы верны:
Вы можете принять ВСЕ ответы?





Вы должны попробовать профилировать правильно, но вместо этого я бы перестал беспокоиться о SendMessage, что почти наверняка не ваша проблема, и подумал бы о перерисовке самого окна.
Вы описываете, что это «окна текстовой консоли», но затем говорите, что у вас их несколько - действительно ли это консоли Windows? Или это то, что рисует ваше приложение?
В последнем случае я бы посмотрел на измерение своего кода рисования и на то, делаю ли я недействительным слишком большую часть окна при каждом обновлении.
Являются ли выходные окна частью одного и того же приложения? Похоже, что они не ...
Если это так, вам следует заглянуть в Шаблон проектирования наблюдателя, чтобы уйти от SendMessage (). Я использовал его для того же типа использования, и у меня он отлично сработал.
Если вы не можете сделать такое изменение, возможно, вы могли бы буферизовать свой вывод примерно на 100 мс, чтобы у вас не было так много исходящих сообщений в секунду, но он также должен обновляться с удобной скоростью.
Я согласен с Уиллом Дином в том, что рисунок в окне консоли или текстовом поле сам по себе является узким местом производительности. Сначала нужно убедиться, что это не ваша проблема. Вы говорите, что рисуете каждую линию целиком, но даже это может быть проблемой, если пропускная способность данных слишком высока.
Я рекомендую вам не использовать SendMessage для передачи данных из основного приложения в текстовое окно. Вместо этого используйте другие средства связи. Это один и тот же процесс? Если нет, вы можете использовать общую память. В некоторых случаях подойдет даже файл на диске. Попросите основное приложение записать в этот файл, а текстовую консоль - прочитать из него. Вы можете отправить уведомление SendMessage в текстовую консоль, чтобы сообщить ей об обновлении представления. Но не отправляйте сообщение всякий раз, когда приходит новая строка. Определите минимальный интервал между двумя последующими обновлениями.
Are the output windows part of the same application? It almost sounds like they aren't...
Да, все в одном процессе.
Я не писал этот код ... но похоже, что SendMessage немного тяжеловат для всего этого в одном случае приложения.
You describe these are 'text console windows', but then say you have multiple of them - are they actually Windows Consoles? Or are they something your application is drawing?
Наше приложение их рисует, это не обычные консоли Windows.
Обратите внимание, что нам также нужно получать данные обратно, когда пользователь вводит в консоль, поскольку у нас довольно часто бывают интерактивные последовательные сеансы. Думайте об этом как о том, что вы видели бы в программе последовательного терминала, но использование внешнего приложения, очевидно, даже дороже, чем то, что мы имеем сейчас.
If you can't make a change like that, perhaps you could buffer your output for something like 100ms so that you don't have so many out-going messages per second, but it should also update at a comfortable rate.
Хорошая точка зрения. Прямо сейчас вывод каждого отдельного символа вызывает отправку сообщения.
И когда мы прокручиваем окно вверх, когда появляется новая строка, мы перерисовываем его построчно.
Обратите внимание, что у нас также есть буфер обратной прокрутки произвольного размера, но прокрутка назад - это интерактивный случай с гораздо более низкими требованиями к производительности.
Также см. Разница в производительности вывода консоли iostream между Windows и OSX?