Russian Qt Forum
Ноябрь 26, 2024, 07:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4] 5   Вниз
  Печать  
Автор Тема: Тормоза в Qt IO  (Прочитано 36981 раз)
BRE
Гость
« Ответ #45 : Январь 12, 2010, 01:07 »

Не может компилятор такое кушать, ибо размер массива во время компиляции не определён, следовательно неизвестно сколько откусывать стека. Специально для этого придумали QVarLengthArray.
Может, это расширение GCC, попробуй сам.
Про визуалы не скажу не знаю.
Записан
Dendy
Гость
« Ответ #46 : Январь 12, 2010, 01:28 »

Что пробовать то? Покажите минимальный рабочий пример.
Записан
BRE
Гость
« Ответ #47 : Январь 12, 2010, 01:34 »

Что пробовать то? Покажите минимальный рабочий пример.
Код
C++ (Qt)
#include <iostream>
 
void func( int sz )
{
       char arr[ sz ];
 
       for( int i = 0; i < sz; ++i )
               arr[ i ] = (char)i;
 
       for( int i = 0; i < sz; ++i )
               std::cout << (int)arr[ i ] << std::endl;
}
 
int main( int argc, char *argv[] )
{
       func( 10 );
       func( 20 );
}
 

и

g++ a.cpp
Записан
Dendy
Гость
« Ответ #48 : Январь 12, 2010, 08:51 »

Действительно, откусывает стек динамически. Проверил в MinGW/GCC4.4.0. А как это соотносится со стандартом?
Записан
BRE
Гость
« Ответ #49 : Январь 12, 2010, 09:34 »

Действительно, откусывает стек динамически. Проверил в MinGW/GCC4.4.0. А как это соотносится со стандартом?
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Variable-Length.html#Variable-Length
Записан
Dendy
Гость
« Ответ #50 : Январь 12, 2010, 09:53 »

Спасибо. Другими словами - этого нет в стандарте. Собственно здесь MSVC ведёт себя корректно. Даже в документации по Qt есть замечание:

Цитировать
The C++ language doesn't support variable-length arrays on the stack. For example, the following code won't compile:

 int myfunc(int n)
 {
     int table[n + 1];  // WRONG
     ...
     return table[n];
 }

Я бы рекомендовал избегать таких конструкций, особенно в кроссплатформенном коде. Тем более, что таким образом стек может закончиться куда быстрее. К примеру попытка создать динамический массив на 2Мб мгновенно обернулась крешем приложения.
Записан
ilot
Гость
« Ответ #51 : Январь 12, 2010, 10:26 »

Невооружённым глазом видно утечку в readString(). Пользуйтесь для этих случаев QVarLengthArray.
можно еще использовать постоянный буфер. Буфер создается один раз, следовательно не нужно при каждом вызове выделять и освобождать память:
Код:
const size_t buffSize = 100;
//...
//где-то при конструировании "объекта-читалки"
unsigned char* buff = new unsigned char[buffSize];

//функция чтения строки
inline QString readString(QFile& f, int count)
{
memset(buff, 0, buffSize);
f.read(buff, count);
return QString(buff).trimmed();
}
//по окончанию чтения файла не забыть зачистку
delete []buff;

Мапится боюсь, размеры могут быть до 10Gb.
Судя по описанию функции
Код:
uchar * QFile::map ( qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions )
отображать файл в память можно кусками, поэтому эту возможность тоже следует рассмотреть

Как справедливо заметил Константин, маленькие утилитарные функции нужно сделать подставляемыми.

По технике: чтобы избежать опечаток и облегчить чтение/понимание кода, "магические" числа лучше заменить на целочисленные константы (const int ...).
Записан
ритт
Гость
« Ответ #52 : Январь 12, 2010, 11:55 »

не-не-не, нафик мемсет...
Код
C++ (Qt)
static inline QString readString(QIODevice *f, int count, uchar* buff)
{
int len = f->read(buff, count);
return QString(buff, len).trimmed();
}
 
Записан
romank
Гость
« Ответ #53 : Январь 12, 2010, 12:25 »

Да и зачем динамическое unsigned char* buff = new unsigned char[buffSize], если размер буфера заранее известен. QString::QString ( const QChar * unicode, int size ) я так понимаю уникод онли, не помогло. Внес все коррективы, видимо компилятор и так достаточно умен, прирост ноль. Трудно ловить точное время с IO.
Записан
ритт
Гость
« Ответ #54 : Январь 12, 2010, 12:36 »

ах, ну, да
return QString::fromUtf8(buff, len).trimmed();
Записан
vaprele07
Гость
« Ответ #55 : Январь 12, 2010, 12:37 »

не стоит городить велосипед: QBuffer + QFile::map
Записан
ритт
Гость
« Ответ #56 : Январь 12, 2010, 12:50 »

и не может быть чтобы приросту было ноль...

смотрю далее:
вместо read вполне можно пропускать по seek;
while (file.pos() != file.size()) - довольно неоптимально, лучше заменить на while (!file.atEnd()) ;
ну, и как уже было сказано ранее, сотня чтений по 4 байта (инт) затратнее одного чтения четырёхсот байт ->
читай документацию по QBuffer (затем будешь читать в байтаррэй н байт, где н - размер твоего блока, завернёшь байтаррэй в буффер и подставишь буффер вместо файла (для этого мы заменили QFile на QIODevice ранее))
Записан
ilot
Гость
« Ответ #57 : Январь 12, 2010, 12:55 »

Да и зачем динамическое unsigned char* buff = new unsigned char[buffSize], если размер буфера заранее известен.
Сам бы я определил отдельный класс для обработки файла, а все эти функции сделал его методами. Отсюда логично, чтобы память для буфера динамически выделялась в его конструкторе и освобождалась в деструкторе, а не заранее в статической области памяти. Собственно только из этих соображений...
не стоит городить велосипед: QBuffer + QFile::map
чем собственно плох метод? все естественно и лаконично.. Существующие решения не всегда самые лучшие в отдельно взятом случае. Тем более выше я писал, что нужно рассмотреть оба варианта и сравнить результат.
Записан
vaprele07
Гость
« Ответ #58 : Январь 12, 2010, 15:03 »

Мапируем или весь файл или нужную область (100 метров или 1гб) "QByteArray::fromRawData" в QBuffer и подставляем в проблемный код.

Хотя возможно я не понял задачу   Непонимающий
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #59 : Январь 12, 2010, 20:38 »

Мапируем или весь файл или нужную область (100 метров или 1гб) "QByteArray::fromRawData" в QBuffer и подставляем в проблемный код.

Хотя возможно я не понял задачу   Непонимающий
+100. Мапить можно не весь файл, а только часть его (чем больше - тем лучше) - на винде будет в разы быстрее работать.
Записан
Страниц: 1 2 3 [4] 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.085 секунд. Запросов: 23.