Как печатать номера строк для текстового поля в С#

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

Но по мере того, как количество строк увеличивается до 50–100 К, прокрутка сильно ухудшается. Я переопределил метод WndProc и обработал все сообщения, чтобы вызвать печать номера строки только при необходимости. (Переопределение OnContentsResized и OnVScroll делает избыточные вызовы метода печати).

Теперь печать номера строки работает нормально, когда количество строк невелико, скажем, до 10 КБ (с этим у меня все в порядке, поскольку редко нужно редактировать файл с 10000 строк), но я хочу снять ограничение.

Несколько наблюдений

  • Количество строк, отображаемых в richtexbox, постоянно +-1. Таким образом, разница в производительности должна быть связана с большим текстом, а не с тем, что я использую графическое рисование.
  • Отрисовка номеров строк для большого текста выполняется медленнее по сравнению с небольшими файлами.

Теперь псевдокод

FIRST_LINE_NUMBER = _textBox.GetFirstVisibleLineNumber();
LAST_LINE_NUMBER = _textBox.GetLastVisibleLineNUmber();
for(loop_from_first_to_last_line_number)
{
    Y = _textBox.GetYPositionOfLineNumber(current_line_number);
    graphics_paint_line_number(current_line_number, Y);
}

Я использую GetCharIndexFromPosition и перебираю RichTextBox.Lines, чтобы найти номер строки в обеих функциях, которые получают номера строк. Чтобы получить позицию Y, я использую GetPositionFromCharIndex для получения структуры Point.

Все вышеперечисленные методы RichTextBox кажутся O(n), что съедает производительность. (Поправьте меня, если я ошибаюсь.)

Я решил использовать двоичное дерево для хранения номеров строк, чтобы улучшить производительность поиска при поиске номера строки по индексу char. У меня есть идея получить структуру данных, которая требует O (n) времени построения, O (nlgn) обновления в худшем случае и O (lgn) поиска.

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


person Ashwini Dhekane    schedule 06.10.2010    source источник


Ответы (1)


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

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

Вторым шагом будет размещение некоторых операторов профилирования или просто использование профилировщика (один из них поставляется с VS 2010), чтобы найти узкое место. Это может оказаться метод нахождения номера строки или что-то еще.

На данный момент я бы только предложил дополнительные исследования. Если вы завершили расследование и у вас есть дополнительная информация, обновите свой вопрос, и я свяжусь с вами соответствующим образом.

person Aliostad    schedule 06.10.2010