Какой самый эффективный способ подсчитать все слова в RichTextbox?

StackOverflow https://stackoverflow.com/questions/2226161

Вопрос

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

 public static int WordCount(this string s)
    {
        s = s.TrimEnd();
        if (String.IsNullOrEmpty(s)) return 0;
        int count = 0;
        bool lastWasWordChar = false;
        foreach (char c in s)
        {
            if (Char.IsLetterOrDigit(c) || c == '_' || c == '\'' || c == '-')
            {
                lastWasWordChar = true;
                continue;
            }
            if (lastWasWordChar)
            {
                lastWasWordChar = false;
                count++;
            }
        }
        if (!lastWasWordChar) count--;
        return count + 1;
    }

Я установил, что количество слов запускается в тексте RichTextbox каждую десятую секунды (если начало выбора отличается от того, что это было в прошлый раз, когда метод запускался). Проблема в том, что количество слов становится медленным при работе над очень длинными файлами. Чтобы решить это, я думаю о том, что слов заполняется только в текущем абзаце, каждый раз записывая подсчет слов и сравнивая его с тем, каким было количество слов в прошлый раз, когда подсчитывается количество слов. Затем это добавило бы разницу между ними к общему количеству слов. Это вызвало бы много осложнений (если пользователь встает, если пользователь удалит абзац, т. Д.) Является ли это логическим способом улучшить количество слов? Или есть что -то, чего я не знаю, что сделает это лучше?

РЕДАКТИРОВАТЬ: Будет ли это работать, чтобы запустить слово в другом потоке? Я не знаю много о потоках, буду исследовать.

Пример текста, который я использовал:

Это было полезно?

Решение

Вы можете сделать более простое количество слов на основе белого пространства:

public static int WordCount(this string s)
{
  return s.Split(new char[] {' '}, 
    StringSplitOptions.RemoveEmptyEntries).Length;
}

MSDN предоставляет этот пример, должно дать вам точное количество слов намного быстрее в больших файлах.

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

Вы также можете использовать очень простой регуляции, которая ищет хотя бы один характер слова и/или апостроф для захвата сокращений:

public static int WordCount(this string s) 
{
    return Regex.Matches(s, @"[\w']+").Count;
}

Это вернется 2141 совпадения (что на самом деле более правильное, чем слово в этом случае, потому что Слово считает единственную звездочку как слово в предложении «нанесла удар A * пальцем»).

Ваш метод на самом деле быстрее, чем предложенный String.Split Метод, почти в три раза быстрее на x86 и более чем в два раза быстрее на X64 на самом деле. Я подозреваю, что JIT возится с вашими временами, всегда запускайте ваши микробенчки в два раза, так как JIT будет занимать подавляющее большинство времени во время вашего первого пробега. И потому что String.Split Был ngen'd, его не нужно собирать в собственный код и, следовательно, будет казаться быстрее.

Не говоря уже о том, что это также более точное, String.Split Считает 7 слов здесь:

Тест :: Это тест

Это также имеет смысл, String.Split Не выполняет никакой магии, и я был бы очень удивлен, если бы создание массива многих строк будет быстрее, чем просто итерация над отдельными символами в строке. Фореация над строкой, очевидно, была очень оптимизирована, когда я пытался unsafe Указатель арифметика, и это было немного медленнее, чем просто foreach. Анкет Я действительно сомневаюсь, что есть какой -нибудь способ сделать это быстрее, кроме того, чтобы быть умным в том, какие разделы в вашем тексте нуждаются в подсчете слов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top