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

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

Страниц: 1 [2] 3 4 5   Вниз
  Печать  
Автор Тема: Тормоза в Qt IO  (Прочитано 36997 раз)
Winstrol
Гость
« Ответ #15 : Июль 29, 2009, 16:43 »

Под .net ещё пробовал читать полностью в память, потом разбирать - медленно и большие затраты памяти (весь файл мне не нужен).
Это самый быстрый способ. Cмотреть на memory mapped file

Выйгрышный вариант оказался читать, пропускать. Я бы с радостью и не читал по одному float, но надо делать пропуски.
Пробовал и через seek, накладно на небольших отступах.
150 метров должно по одном float'у читаться за твое время. Если пропускать, должно быть быстрее. Что-то у тебя не то.
Цитировать
Посмотрел в src: read читывает в 4kb буффер.
Как можно отказатся от буферирования?
Это немного. Желательно читать в больший буфер в зависимости от структуры файла. И когда данные в файл пишешь, голову никто не отменял. Полезную информацию надо писать блоками, а не разбрасывать по файлу.
Записан
romank
Гость
« Ответ #16 : Июль 29, 2009, 20:11 »

Значит надо повторится специально для вас.
Приведенный ранее код C# характерен:
пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было.
Дефолтное считывание по 4kb, как вообще было понятно из обсуждения, видимо не так хорошо в моём случае. Хотя не было утверждения об обратном.
Про голову хорошо написано, только не понятно зачем.
Не все форматы файлов придуманы (к сожалению) мной и порой приходится читать как дают, а не как хочется, в соответствии с technical description.
Поэтому как-то с сомнением отношусь к вашей рекомендации. Но всё равно спасибо.
Записан
Winstrol
Гость
« Ответ #17 : Июль 29, 2009, 22:23 »

Значит надо повторится специально для вас.
Приведенный ранее код C# характерен:
пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было.
Ну, тогда другое дело. Должно работать быстро. Нужно делать замеры времени работы различных участков кода
хотя бы с помощью clock() из <time.h>, чтобы понять, где тормозит.
Записан
Tonal
Гость
« Ответ #18 : Июль 30, 2009, 07:26 »

пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было.
Дефолтное считывание по 4kb, как вообще было понятно из обсуждения, видимо не так хорошо в моём случае. Хотя не было утверждения об обратном.
Чтобы отключить буферизацию, нужно добавить флаг QIODevice::Unbuffered при открытии.
Хотя тот порядок считывания, что ты привёл довольно нормально ложится в буфер 4кб - ведь большинство чтений из буфера.

Короче профилировать нужно а не пальцем в небо тыкать. Улыбающийся
Записан
romank
Гость
« Ответ #19 : Июль 30, 2009, 07:42 »

Ваше "короче профелировать надо" и "нужно делать замеры времени" было предложено за день. Пальцем в небо нет не тыкал, даже не понимаю к чему это относится.
Вообще мною получены практически все рекомендации и советы, последние сообщения излишне.
Спасибо всем.
Записан
Tonal
Гость
« Ответ #20 : Июль 30, 2009, 10:32 »

Главные советы - учить язык и читат Ассистента тебе вроде здесь ещё никто не давал.
А по твоиму коду и вопросам они таки напрашиваются. Улыбающийся

Да, Qt - это библиотека а не язык или платформа. Поэтому "профиляторов под Qt" ты не найдёшь. Улыбающийся
Искать нужно профилятор под тот компилятор, на котором работаешь. Улыбающийся
В мингве, как и в gcc для этого используется опция -pg и тулза gprof

П.С. 2 Moderators Предлогаю вынести разделить топик.
Начиная с поста #24 вынести в отдельную тему "Тормоза в Qt IO".
« Последнее редактирование: Июль 30, 2009, 10:39 от Tonal » Записан
romank
Гость
« Ответ #21 : Июль 30, 2009, 11:36 »

Я не знаю конечно, где в моем коде вопиющее незнание языка.
Обычный код, обычные вопросы. Ассистента читать умею. И на гугле не забанен !
Те кто отвечал вначале, понимают о чем вопрос.
Те кто отвечают в конце с трудом понимают в чем вообще дело.
Причем здесь "Да Qt это библибиотека" и так далее. Ясно же о чем спрашивал.

Не надо никаких "Тормоза в Qt", Qt не тормозит.
Надо переименовать в " Qt. Fast read binary file"
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #22 : Июль 30, 2009, 13:44 »

пиши только так:
char m_buffer[sizeof(float)];

Стоит упомянуть, что VLA в C++ доступны только как расширение GCC.
Записан
BRE
Гость
« Ответ #23 : Июль 30, 2009, 13:52 »

пиши только так:
char m_buffer[sizeof(float)];

Стоит упомянуть, что VLA в C++ доступны только как расширение GCC.
sizeof(float) константа времени компиляции.
Записан
Winstrol
Гость
« Ответ #24 : Июль 30, 2009, 15:00 »

Стоит упомянуть, что VLA в C++ доступны только как расширение GCC.
Теперь уже наверное не расширение, а поддержка C99. У Intel C++ тоже есть.
Записан
Tonal
Гость
« Ответ #25 : Июль 31, 2009, 12:27 »

Вы спрашивали, мы отвечаем! Улыбающийся
Я не знаю конечно, где в моем коде вопиющее незнание языка.
Ответ #5, первый фрагмент С++:
Непонимание отличий от управляемых языков в работе с памятью.
Использование "магических констант" вместо sizeof.
Использование "приведения в стиле С" вместо reinterpret_cast.

Ассистента читать умею. И на гугле не забанен !
Ответ #5, второй фрагмент С++:
Использование read вместо seek.
Ответ #13
Ненайти константы отключения буферизации файла при открытии...

Причем здесь "Да Qt это библибиотека" и так далее. Ясно же о чем спрашивал.
Ответ #9
Вопрос совершенно бессмысленен.
Я, например, в основном пишу на Python + PyQt.
Что тебе может дать мой корректный ответ использовать стандартный python-овский профилер? Улыбающийся

Что же касается тормрзов при чтении, то общий совет читать большими буферами, а потом из них уже восстанавливать нужные структуры в памяти.
Идеально если структуры файла фиксированной длинны - тогда читаем буфер в несколько длинн записи.
Если нет - читаем чтобы вместилось например от 10 до 100 или от 100 до 1000 записей.
Т.к. чтение с диска самая затратная операция, то и выигрышь получаем соответственный. Улыбающийся
Тут нормально подойдёт отображение в память, только нужно учитывать, что система отображает тоже с какой-то гранулярностью, например 4к или 64к. Поэтому, по хорошему, размер отображения должен быть кратен этой гранулярности. Улыбающийся
Записан
romank
Гость
« Ответ #26 : Июль 31, 2009, 14:07 »

Это что обвинение на которое я должен дать ответ?

Если быть серьезным: cpp это не первый мой язык, я начинал с обычной (когда-то) цепочки basic->asm (Z80), потом универский pascal который перерос в delphi, далее C# и сейчас C++, читаю но не пишу на FORTRAN. Но программирование не стало моей основной работой, я занимаюсь сейчас научной деятельностью (это нет не оправдание моему как говорится "плохому" коду. Сомневаюсь кто ещё лучше пишет : научный специалист в своей области, знающий досконально о чем пишет или абстрактный программист работающий по техзаданию за деньги).

Так что я наверно достаточно понимаю отличия одного языка от другого. Каюсь не всегда достаточно интереса и времени для чтения "сахара" присущего языку. Можете не спрашивать меня про итераторы и паттерны программирования. Мне достаточно циклов, переходов, простых классов и классов предоставляемых языком (или фреймворком). Не важно насколько красива твоя программа если она не работает.

Поверьте я знаю что делает sizeof, использование постоянной 4 не является чем то специальным. В 90% случаев использую sizeof, например:
Код
C++ (Qt)
glBufferData(GL_ARRAY_BUFFER, 3 * vertexCount * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
 
Tonal молодец, читает классиков (что и не по ленился показать).

Что там дальше.
Использование приведения в стиле C. Да виноват, читал в бытность около бассейна Страуструпа и K&R. Отложились листинги C в голове. Какое это все таки серьезное замечание, как это изменило конечный результат.

Ещё раз про приведенный код C#. Этот кусок кода был подсмотрен в реализации Microsoft стандартного класса BinaryReader, упрощенный его вариант вошел в мою программу на C#. Далее при портировании, я занимался практически эквивалентным переводом из C# в C++.
Знающие люди подсказали как сделать проще. Спасибо, сделал чуть проще.
Выйграл? Нет не выйграл. Понял ли я что советовали? Да, понял.
В данный момент есть гораздо более узкие места, то что ещё не портировано.
Главная цель дойти до конца.

Что там ещё.
Использование read вместо seek? Я конечно, как вы видите, не очень большой специалист.
Гугл подсказал, что совпало с моим мнением, что seek на маленькие расстояния проигрывает холостому чтению read.
Могу конечно и на seek изменить, но мне не хочется ставить излишние опыты.
(Поэтому кстати я и здесь).

Не найти константы отключения буфферизации? Читаем:
"In other cases, the restriction may be due to the implementation, or may be imposed by the underlying platform; for example, QTcpSocket does not support Unbuffered mode, and limitations in the native API prevent QFile from supporting Unbuffered on Windows."

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

Всё что дальше написано уже было.
Название темы "Тормоз..." и так далее придумал не я. Общие советы знаю.

Нужен был человек имеющий схожую ситуацию, с работающим кодом, который потратил своё драгоценное время на "а давай попробуем вот так" или "а может быть вот это".

Итак что в итоге. Вы рассказали что читали классиков и пишете на питоне.
Эй, вы молодец !
Записан
Tonal
Гость
« Ответ #27 : Август 03, 2009, 07:56 »

Это что обвинение на которое я должен дать ответ?
Это не обвинение - каждый пишет так, как ему больше нравится. Улыбающийся
Но по тому что и как написано можно с лёгкостью понять насколько профессиональный человек это писал.
Думаю, что в своей области ты тоже с лёгкостью отличишь дилетанта от профи не особенно вчитываясь в написанное. Улыбающийся
Это собственно ко всяким sizeof и приведениям. Улыбающийся

А вот по поводу "сахора" ты ошибаешься.
Сахар - это всяческие foreach-и проперти и LINQ. Те же параметры по умолчанию - тоже сахар.
Но работа с памятью и сборка мусора - базовое отличие управляемых языков (C#, Python) от неуправляемых (С++, Delphi,  FORTRAN, Asm).
В управляемых у тебя нет прямого доступа к памяти и для чтения приходится извращатся как в BinaryReader. В неуправляемых ты просто читаешь файл в указанную область, что тебе и подсказали. Улыбающийся

По поводу read вместо seek - это преждевременная оптимизация.
В данном случае она просто ухудшает читабельность кода, но не даёт никакого существенного выигрыша. Улыбающийся
Т.е. опять же - придирки к стилю. Улыбающийся

Про скорость - совет один - читай большими блоками и их уже разбирай. Т.е. собственная буферизация.
Ну и профилирование реализации. Улыбающийся

Про  профилятор - всё зависим от компилятора и операционки.
Ежели ты под мингвой - есть стандартный (правда не гуёвый)
Ежели под MSVC - то вроде есть в поставке начиная с про версий, есть Intel® VTune, есть AMD CodeAnalyst, есть AQtime.
Все по разному платные. Улыбающийся

Ну и классиков читать всяко нужно и полезно! Улыбающийся
Записан
romank
Гость
« Ответ #28 : Август 03, 2009, 08:26 »

Qt4.5 + mingv + winxp.
Зачем же вы всё рассказываете мне про память, я прекрасно знаю и даже помню asm. Даже у классиков (пишу по памяти) начинается с перебора в цикле for и заканчивается while (*p++ == *v++). То есть работа с указателями это НЕ преждевременная оптимизация, а замена read на seek это преждевременная? Для меня работа с указателями больше затрудняет чтение листинга, чем read на seek.
Про сахар так и писал, всякие linq foreach и др. требуют дополнительного времени для изучения, может быть не всегда оправданного.
Профессионала от дилетанта можно отличить не по красивости кода, а по умению эстетического алгоритмического мышления. Каждому кто показал более красивые решения, я сказал своё спасибо.

На сегодняшний день я отложил изменения в считывании файла - буфферирование и прочее сильно изменят код. Сейчас доработаю с opengl и вернусь к этой теме.

До скорых встреч.
Записан
romank
Гость
« Ответ #29 : Август 03, 2009, 12:19 »

!!!
После перезагрузки первый запуск дает 5000ms. Повторные запуски 109ms.
Далее закрывая программу, открывая другие данные (примерно считано 2Gb данных)  и наконец опять открывая первый пример те же 109ms.

Оптимизация никакая не нужна. 109ms это отличный результат, но что происходит в первый раз при запуске Qt программ? Или у меня жесткий диск буфферизирует 2Gb?
Чертовщина.
Записан
Страниц: 1 [2] 3 4 5   Вверх
  Печать  
 
Перейти в:  


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