Как напечатать номера строк для текстового поля в C # - PullRequest
4 голосов
/ 06 октября 2010

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

Но по мере увеличения количества строк от 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), что снижает производительность. (Поправь меня, если я ошибаюсь.)

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

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

1 Ответ

2 голосов
/ 06 октября 2010

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

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

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

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

...