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

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

Страниц: 1 2 [3] 4 5   Вниз
  Печать  
Автор Тема: Тормоза в Qt IO  (Прочитано 36990 раз)
Tonal
Гость
« Ответ #30 : Август 04, 2009, 08:48 »

Начиная с ХР-юши в винду встроен оптимизатор запуска программ. Ранее входил в состав утилит Нортона, если мне не изменяет склероз.
При первом запуске в сеансе он собираеат и сохраняет дополнительную инфу о проге и нужных её дополнительных модулях. Поэтому последующие запуски происходят существенно быстрее.

Про оптимизацию: работа с указателями для чистого С - это естественная и стандартная работа. Там нет массивов и строк как таковых. Есть примитивные типы и области памяти. Улыбающийся
Хорошо знающий С человек читая while (*p++ == *v++); видит просто копирование строки - это идеома.
Да и компилятор знает такие идеомы и вполне может соптимизировать в инструкции копирования строки, например. Улыбающийся

А вот в C# подобный код может быть нужен только для работы с внешними unsefe интерфейсами.
Ведь в чистом шарпе нет областей памяти и работы с голыми указателями. Есть массивы и строки. Ты не занимаешься распределением памяти, но лишен низкоуровневых возможностей. Улыбающийся

Именно по этому увидев твой код, я предположил что ты не понимаешь различия моделей памяти. Вполне возможно просто не задумывался. Улыбающийся

П.С. http://www.opennet.ru/docs/RUS/gprof/ - хорошее описание стандартного профилера под gcc/mingw.

П.П.С. Первый мой учитель по программированию говорил:
Написать фортрановскую программу можно на любом языке! Улыбающийся
Он преподавал нам язык REFAL - это что-то среднее между функциональным и логическим программированием. Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #31 : Август 04, 2009, 09:08 »

Хорошо знающий С человек читая while (*p++ == *v++); видит просто копирование строки - это идеома.
лично я вижу недоделанное сравнение в лучшем случае
Записан
Tonal
Гость
« Ответ #32 : Август 04, 2009, 10:44 »

Хм, действительно сравнение.
Хотя от копирования оно отличается только одним оператором.
Глаз уже замылился на python-е. Улыбающийся
Записан
spectre71
Гость
« Ответ #33 : Август 04, 2009, 13:05 »

Копирование:
while ((*p++ = *v++));
Записан
romank
Гость
« Ответ #34 : Январь 10, 2010, 23:51 »

Так и не смог ничего сделать.
.net работает с файлами большого объема раза в два быстрее чем C++.
Qt здесь не причем.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #35 : Январь 10, 2010, 23:53 »

если учесть, что .net написан сам на с++...
и потом, ты же написал что всё ок после повторного запуска. Такой еще вопрос - в .нете и 1й запуск не тормозит? И код бы финальный увидеть
« Последнее редактирование: Январь 11, 2010, 00:11 от Авварон » Записан
romank
Гость
« Ответ #36 : Январь 11, 2010, 15:15 »

В .net также первый запуск самый долгий, следующие моментальные.
Код выложить конечно могу, но без данных он будет бесполезен и вообще объемно для форума. Если интересно приватно покажу, может быть свежий взгляд подскажет что. Мнение толпы бесполезно.
Записан
ритт
Гость
« Ответ #37 : Январь 11, 2010, 19:29 »

а весь код и не нужен. интересен код "читалки"...
Записан
romank
Гость
« Ответ #38 : Январь 11, 2010, 20:10 »

Код
C++ (Qt)
QString readString(QFile& f, int count)
{
char* c = new char[count + 1];
f.read(c, count);
c[count] = 0;       // Null terminated
return QString(c).trimmed();
}
 
void readFloatbuffer(QFile &f, float*  f_buffer, int len)
{
f.read((char*)f_buffer, len * sizeof(*f_buffer));
}
 
void readInt32buffer(QFile &f, int*  i_buffer, int len)
{
f.read((char*)i_buffer, len * sizeof(*i_buffer));
}
 
int readInt32(QFile &f)
{
int val;
f.read((char*)&val, sizeof(val));
return val;
}
 
float readFloat(QFile &f)
{
float val;
f.read((char*)&val, sizeof(val));
return val;
}
 
//Implementation
TempestDataLoader::TempestDataLoader(SharedData* data)
{
m_data = data;
}
 
TempestDataLoader::~TempestDataLoader()
{
}
 
void TempestDataLoader::loadDataFromFile(QString fName)
{
QTime timer;
timer.start();
 
m_data->fileName = fName;
int numb[100];
 
// Prepare for read file
QFileInfo fileInfo(fName);
QString baseName = fileInfo.baseName();
QString pathName = fileInfo.absolutePath();
QString fname(pathName + "/" + baseName + ".mis");
 
// Read mis-file
QFile file(fname);
file.open(QIODevice::ReadOnly);
 
file.read(16);
int d = readInt32(file);
int m = readInt32(file);
int y = readInt32(file);
 
m_data->initDate.setDate(y, m, d);
file.read(54);
 
m_data->progHeader1 = readString(file, 75);
m_data->progHeader2 = readString(file, 75);
file.read(12);
 
readInt32buffer(file, numb, 100);
 
m_data->wellCount = numb[2];
m_data->groupCount = numb[11];
m_data->aquaCount = numb[32];
m_data->quantCount = numb[37];
m_data->nx = numb[43];
m_data->ny = numb[44];
m_data->nz = numb[45];
 
file.read(12);
int nc = readInt32(file);
int nl = readInt32(file);
readInt32(file);
int ms = readInt32(file);
int mp = readInt32(file);
file.read(mp * 16 + nc * 16 + mp * 4 + nc * mp * 4 + mp * 4 + 3 * nc * 4 + nl * 16 + nc * nl * 4 + ms * 16 + nc * ms * 4);
m_data->oilden = readFloat(file);
m_data->gasden = readFloat(file);
m_data->waterden = readFloat(file);
 
file.close();
 
// Read ctl-file
m_data->daysList.clear();
m_data->datesList.clear();
m_data->arrayList.clear();
m_data->yearsIndex.clear();
 
fname = pathName + "/" + baseName + ".ctl";
 
file.setFileName(fname);
file.open(QIODevice::ReadOnly);
 
file.read(12);
 
while (file.pos() != file.size())
{
readInt32(file);
int isArray = readInt32(file);
int isRate = readInt32(file);
float value = readFloat(file);
 
if (isArray == 1) m_data->arrayList.append(m_data->initDate.addDays((int)value));
if (isRate == 1)
{
m_data->daysList.append(value);
m_data->datesList.append(m_data->initDate.addDays((int)value));
if (m_data->datesList.last().month() == 01)
{
m_data->yearsIndex.append(m_data->datesList.count() - 1);
}
}
 
file.read(8);
}
file.close();
 
m_data->daysCount = m_data->daysList.count();
m_data->yearsCount = m_data->yearsIndex.count();
 
// Read rat-file
fname = pathName + "/" + baseName + ".rat";
 
file.setFileName(fname);
       file.open(QIODevice::ReadOnly);
 
m_data->wellNames.clear();
m_data->groupNames.clear();
m_data->aquiferNames.clear();
       m_data->quantMnemonic.clear();
       m_data->quantUnits.clear();
       m_data->quantAssociated.clear();
       m_data->quantDescription.clear();
 
for (int i = 0; i < m_data->wellCount; ++i) m_data->wellNames.append(readString(file, 16));
for (int i = 0; i < m_data->groupCount; ++i) m_data->groupNames.append(readString(file, 16));
       for (int i = 0; i < m_data->aquaCount; ++i) m_data->aquiferNames.append(readString(file, 16));
       for (int i = 0; i < m_data->quantCount; ++i)
       {
           m_data->quantMnemonic.append(readString(file, 16));
           m_data->quantUnits.append(readString(file, 16));
           m_data->quantAssociated.append(readString(file, 16));
           m_data->quantDescription.append(readString(file, 48));
           file.read(numb[39] * 4 + numb[40] * 4);
       }
 
int leng = (numb[20] + numb[1] + 1) * (numb[15] + 2) + 2 * numb[20] + 4 * numb[1] + 2 * numb[1] * numb[4];
 
// Found  max-array of float
int fbufflen = numb[48];
if (fbufflen < 15) fbufflen = 15;
if (fbufflen < leng) fbufflen = leng;
float* fbuff = new float[fbufflen];
int* ibuff = new int[numb[46]];
 
// Initialization
m_data->init();
 
int _status = 0;
for (int istep = 0; istep < m_data->daysCount; ++istep)
{
for (int iw = 0; iw < m_data->wellCount; ++iw)
{
readInt32buffer(file, ibuff, numb[46]);
_status = ibuff[3];
 
//IRPTR + IRLIM
file.read(numb[4] * numb[47] * 4 + numb[6] * 2 * 4);
 
//WRATE
readFloatbuffer(file, fbuff, numb[48]);
 
m_data->xloc[iw] = fbuff[0];
m_data->yloc[iw] = fbuff[1];
 
//WRVOL
readFloatbuffer(file, fbuff, 15);
 
m_data->opr[istep * m_data->wellCount + iw] = 0;
m_data->gpr[istep * m_data->wellCount + iw] = 0;
m_data->wpr[istep * m_data->wellCount + iw] = 0;
m_data->wir[istep *  m_data->wellCount + iw] = 0;
 
if (_status == 1)
{
m_data->opr[istep * m_data->wellCount + iw] = fbuff[0];
m_data->gpr[istep * m_data->wellCount + iw] = fbuff[1];
m_data->wpr[istep * m_data->wellCount + iw] = fbuff[2];
}
 
if (_status == 2)
{
m_data->wir[istep * m_data->wellCount + iw] = fbuff[1];
}
 
m_data->opt[istep * m_data->wellCount + iw] = fbuff[5];
m_data->gpt[istep * m_data->wellCount + iw] = fbuff[6];
m_data->wpt[istep * m_data->wellCount + iw] = fbuff[7];
m_data->wit[istep * m_data->wellCount + iw] = fbuff[11];
 
//WRMS + WMCMP + WRCMP
file.read(numb[1] * 3 * 4 + numb[4] * 2 * 4 + numb[4] * numb[1] * 4);
 
//WVCMP
if (numb[54] == 1)
file.read(numb[4] * 15 * 4);
 
//WVLAY
if (numb[55] == 1)
file.read(numb[4] * numb[51] * 4);
}
 
//Group data
for (int ig = 0; ig < m_data->groupCount; ig++)
{
file.read(4);
readFloatbuffer(file, fbuff, leng);
 
file.read(numb[20] * numb[52] * 4);
 
for (int iw = 0; iw < m_data->wellCount; iw++)
{
m_data->gwfr[ig *  m_data->wellCount  + iw] =readFloat(file);
}
 
file.read(numb[4] * numb[53] * 4);
}
 
//Aquifer data
file.read(numb[32] * numb[33] * 4);
 
// Quantities
                   for (int iq = 0; iq < m_data->quantCount; ++iq)
                   {
                       m_data->qdata[istep * m_data->quantCount + iq] = readFloat(file);
                   }
 
}
file.close();
 
delete[] ibuff;
delete[] fbuff;
 
m_data->elapsedTime = timer.elapsed();
}
 
« Последнее редактирование: Январь 11, 2010, 20:13 от romank » Записан
Dendy
Гость
« Ответ #39 : Январь 11, 2010, 20:32 »

Невооружённым глазом видно утечку в readString(). Пользуйтесь для этих случаев QVarLengthArray.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



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

А все-таки почему отображение в файлов в память (memory mapped files) не попробовать? У меня на больших файлах (~1GB) давало существенный выигрыш. Тогда все эти почти все эти read превратятся просто в операции приведения типов указателей, а о проблеме медленных seek для коротких интервалов вообще забыть можно.
« Последнее редактирование: Январь 11, 2010, 20:55 от xokc » Записан
romank
Гость
« Ответ #41 : Январь 11, 2010, 23:11 »

Я портируюсь с дотнета, ожидал некоторого увеличения скорости. Утечки ликвидируем. Мапится боюсь, размеры могут быть до 10Gb.

UPD. Вспомнил, утечка появилась благодаря переходу на MS компилятор, мингв спокойно кушал:

QString readString(QFile& f, int count)
{
   char c[count + 1];
   f.read(c, count);
   c[count] = 0;       // Null terminated
   return QString(c).trimmed();
}
« Последнее редактирование: Январь 11, 2010, 23:19 от romank » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #42 : Январь 11, 2010, 23:23 »

const int напиши и мелкомягкий тоже съест... долже по крайней мере
Записан
Dendy
Гость
« Ответ #43 : Январь 12, 2010, 00:02 »

Не может компилятор такое кушать, ибо размер массива во время компиляции не определён, следовательно неизвестно сколько откусывать стека. Специально для этого придумали QVarLengthArray.
Записан
ритт
Гость
« Ответ #44 : Январь 12, 2010, 00:59 »

сегодня код уже смотреть не буду (лень уже), но сходу вижу каку:
void readFloatbuffer(QFile &f, float*  f_buffer, int len)
заменяем на
static inline void readFloatbuffer(QFile *f, float*  f_buffer, int len)
или на
static inline void readFloatbuffer(QIODevice *f, float*  f_buffer, int len)
, что универсальнее

и по аналогии...

/*тэгом "код" пользоваться тоже лень Улыбающийся */
Записан
Страниц: 1 2 [3] 4 5   Вверх
  Печать  
 
Перейти в:  


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