Ускорение вывода текста в Windows для консоли

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

Текущий код структурирован так, что окно живет своей маленькой жизнью, а основной поток приложения управляет им через вызовы «SendMessage ()». Эта передача сообщений, кажется, является причиной невероятных накладных расходов. По сути, обход ОС кажется неправильным.

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

Я не эксперт в кодировании Windows, поэтому мне нужно спросить сообщество, есть ли какая-то другая архитектура для отображения текста в окне, кроме отправки таких сообщений? Вроде довольно тяжеловес.

Обратите внимание, что это на C++ или обычном C, поскольку основное приложение - это переносимая программа на C / C++ / некоторых других языках, которая также работает в Linux и Solaris.

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

Итак, я полагаю, что все приведенные ниже советы верны:

  • Посмотрите, сколько всего перерисовывается
  • Рисуйте вещи напрямую
  • Операции отрисовки фрагментов во времени, чтобы не отправлять каждый символ на экран, стремясь к частоте обновления 10–20 Гц последовательной консоли.

Вы можете принять ВСЕ ответы?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
1 489
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы должны попробовать профилировать правильно, но вместо этого я бы перестал беспокоиться о 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.

Хорошая точка зрения. Прямо сейчас вывод каждого отдельного символа вызывает отправку сообщения.

И когда мы прокручиваем окно вверх, когда появляется новая строка, мы перерисовываем его построчно.

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

Другие вопросы по теме