Как я могу улучшить скорость qtextedit :: setplaintext () в qt?

Недавно я написал TextEditor проект, загруженный в Github. В проекте завершена основная функция текстового редактора!

Однако меня не устраивает скорость открытия большого файла.

Например, при открытии файла размером 540 КБ стоимость readAll() составляет 18 мсек, а стоимость setPlainText() составляет 42s, что раздражает. Как я могу улучшить производительность своего кода? Вы можете дать мне совет? Заранее спасибо.

Мой основной код ниже:

// textedit.cpp 
#define qcout qDebug()
bool TextEditor::readFile(const QString &fileName)
{
    QFile file(fileName);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox::warning(this, tr("TextEditor"),
                             tr("Cannot read file %1.\n%2.")
                             .arg(file.fileName())
                             .arg(file.errorString()));
        return false;
    }

    //QTextStream inFile(&file);
#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
    QTime t1, t2, t3, t4;
    t1 = QTime::currentTime();
    const QByteArray data = file.readAll();     // 18ms
    t2 = QTime::currentTime();
    qcout << t1.msecsTo(t2);
    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    const QString text = codec->toUnicode(data.constData(), data.size(), &state);
    //qcout << text;
    t3 = QTime::currentTime();
    qcout << t2.msecsTo(t3);
    if (state.invalidChars > 0)
    {
        // Not a UTF-8 text - using system default locale
        QTextCodec * codec1 = QTextCodec::codecForLocale();
        qcout << codec1->name();
        if (!codec1)
            return false;
        qcout << "invalidChars > 0";
        setPlainText(codec1->toUnicode(data));
    }
    else
    {
        qcout << "invalidChars = 0";
        setPlainText(text);
    }
    t4 = QTime::currentTime();
    qcout << t3.msecsTo(t4);              // 42s annoying!
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif
    return true;
}

Результат:

18
1
invalidChars = 0
42126

Что это за язык программирования? Возможно, вы захотите изменить теги на свой вопрос.

necko 11.04.2018 13:53

@necko Qt - кроссплатформенный фреймворк приложений с использованием C++.

JosanSun 11.04.2018 13:59

Возможно, вам придется читать данные так же, как и вы, но затем разбить их на более мелкие части, которые затем можно будет установить в виджете как обычный текст. Таким образом, вам может потребоваться учитывать прокрутку / изменение размера / разрывы строк. Не уверен, возможно ли это.

FrozenTarzan 11.04.2018 14:05
QTextEdit, как известно, работает медленно из-за своих возможностей компоновки. Вы можете рассмотреть возможность использования других виджетов для вашего текста, например QPlainTextEdit.
vahancho 11.04.2018 14:05

@vahancho Сейчас стоит 32s, но все равно раздражает ...

JosanSun 11.04.2018 14:37

Какова структура (кодировка, набор символов, языковой стандарт) вашего тестового файла? загрузите его в свой репозиторий.

Mohammad Kanan 11.04.2018 18:54

@MohammadKanan Я загрузил свой тестовый файл в папку testFile. Его имя - longline.txt.

JosanSun 12.04.2018 03:12
1
7
556
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Имя тестового файла уже рассказывает историю (longline.txt).

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

Поскольку ваш файл в основном представляет собой очень длинное отдельное «слово», плохой QTextEdit не имеет другого выбора, кроме как сканировать весь файл искать его конец.

Если вы добавите эту строку в конструктор:

setWordWrapMode(QTextOption::WrapAnywhere);

вы можете переопределить режим переноса по умолчанию. Когда установлен QTextOption :: WrapAnywhere, перенос может происходить в любой точке строки (проверьте документацию здесь).

Для справки, моей машине потребовалось всего 199 мс, чтобы загрузить файл и отобразить его.

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

Мой результат теста около 1000 мс. Спасибо. Результат приемлемый.

JosanSun 12.04.2018 13:21

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