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

Это будет длинный пост. Я хотел бы иметь предложения, если таковые имеются, по процедуре, которой я следую. Я хочу, чтобы лучший способ печатать номера строк рядом с каждой строкой с завершением 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)


arrow_upward
2
arrow_downward

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

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

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

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

person Aliostad    schedule 06.10.2010