Название: Тормоза в Qt IO Отправлено: romank от Июль 27, 2009, 07:53 Почему не Windows95? :)
Сейчас переписываю свой проект под qt. Заметил черезвычайное падение производительности при I/O операциях. После перехода на unsafe скорость обработки файлов (~1Gb) достигла 2 секунд. Под Qt я пока болтаюсь на уровне 8-10 секунд. В форумах советуют начать проецировать в память. .net быстрее работает со считыванием файлов? P.S. Вообще надо было мне завести отдельную нитку, но и так по поводу i/o было много написано. Название: Тормоза в Qt IO Отправлено: Rcus от Июль 27, 2009, 08:06 Крутая у вас I/O подсистема, у меня винты на линейном чтении дают всего примерно 100МиБ/с
Название: Тормоза в Qt IO Отправлено: romank от Июль 27, 2009, 09:01 Да, действительно.
Хотел сказать про то что файлы могут достигать объема ~1Gb. Далее читать: 2 секунды на 110Mb в .net и 8 секунд в Qt. Название: Тормоза в Qt IO Отправлено: Rcus от Июль 27, 2009, 09:09 Все равно не верю в такую разницу. Без графа профайлера утверждать ничего не могу, но помоему дело в не реализации I/O подсистемы Qt, а в алгоритмах обработки.
Название: Тормоза в Qt IO Отправлено: Admin от Июль 27, 2009, 10:18 Насчет windows 98 и 2000 - много работаю на научные организации.
Виндоус им покупать очень дорого да и нафига. по поводу файлов - если памяти много, то мапим файл в память и обрабатываем. Название: Тормоза в Qt IO Отправлено: romank от Июль 27, 2009, 11:47 Специфика моей (формально научной) работы связана с рабочими станциями.
Программа которую я пишу 100% будет использоватся на не слабых машинах под XP. Для портирования с .NET (причины: обработка больших массивов данных, полагал что openGL на Qt будет быстрее [но сегодня вижу что реализация отрисовки в QGLWiget оставляет желать лучшего, низкий FPS, сражаюсь из последних сил, дай мне сил волшебный бубен]) переписывал основной код, суть которого считывать последовательно Int32 и Float из бинарного файла. В .net реализации ввел следующее (это уже последние этапы оптимизации, после которых скорострельность показалась мне достаточной): Код
Здесь всё просто, читаю четыре байта и через указатель "обзываю" float`ом. Также для Int. Вот кусочек кода в котором используются вызовы: Код
То есть большое количество мелких считываний до 100 байт за раз. В Qt переписал практически также: Код
Использование: Код
Провал в производительности. При первом вызове черезвычайно медленно (как-то неэффективно работает буфферирование чтоли), потом вроде нормально. Пробовал считывать большие куски и разбирать их в памяти. Прироста заметного не получил. Мапить в память можно, но даст ли это мне достаточного ускорения? Может как-то меньшей кровью можно обойтись? Название: Тормоза в Qt IO Отправлено: BRE от Июль 27, 2009, 12:06 А для чего читать в один буфер, а затем перекладывать во второй?
Можно же просто: Код
Название: Тормоза в Qt IO Отправлено: romank от Июль 27, 2009, 12:17 Отличный совет, мне не хватает ещё моего знания cpp.
Меня сбило с толку что падение производительности отмечалось при первом запуске. Теперь всё хорошо. Буду дальше бороться за opengl. UPD: Подскажите, как сделать проще следующее: Код
UPD: Забыл добавить, основной причиной перехода на Qt стало отличное GUI. Название: Тормоза в Qt IO Отправлено: spectre71 от Июль 27, 2009, 12:49 Отличный совет, мне не хватает ещё моего знания cpp. Меня сбило с толку что падение производительности отмечалось при первом запуске. Теперь всё хорошо. Буду дальше бороться за opengl. UPD: Подскажите, как сделать проще следующее: Код
UPD: Забыл добавить, основной причиной перехода на Qt стало отличное GUI. Код
никогда не пиши так: char m_buffer[4]; пиши только так: char m_buffer[sizeof(float)]; Название: Тормоза в Qt IO Отправлено: romank от Июль 29, 2009, 10:45 Да, поспешил радоватся, всё осталось также.
Подскажите какие есть профайлеры под Qt? Название: Тормоза в Qt IO Отправлено: BRE от Июль 29, 2009, 10:58 Да, поспешил радоватся, всё осталось также. Меня сбило с толку что падение производительности отмечалось при первом запуске. Теперь всё хорошо. Думаю, что это происходит из-за того, что при первом запуске файл реально читается с диска, при последующих запусках этот файл храниться в дисковом кэше и данные с диска не читаются.Можно попробовать использовать буферизацию при чтении, т.е. читать большими кусками, а разбор данных делать из оперативной памяти. Название: Тормоза в Qt IO Отправлено: pastor от Июль 29, 2009, 12:35 Подскажите какие есть профайлеры под Qt? Глянь вот этот топик http://www.prog.org.ru/topic_2196_0.html Название: Тормоза в Qt IO Отправлено: Winstrol от Июль 29, 2009, 13:10 Подскажите, как сделать проще следующее: Самое логичное так:Код
Код Но читать по 1 float'у из файла идея плохая. Название: Тормоза в Qt IO Отправлено: romank от Июль 29, 2009, 14:27 Под .net ещё пробовал читать полностью в память, потом разбирать - медленно и большие затраты памяти (весь файл мне не нужен).
Выйгрышный вариант оказался читать, пропускать. Я бы с радостью и не читал по одному float, но надо делать пропуски. Пробовал и через seek, накладно на небольших отступах. Посмотрел в src: read читывает в 4kb буффер. Как можно отказатся от буферирования? Про оптимизацию читал до вопроса ветку. В итоге под win не нашел бесплатного решения. Может мне и не нужен профайлер? Хочется (макимально) какие участки кода наиболее затратны? (минимально) Сделать самому замеры. Какой аналог StopWatch есть в Qt? Название: Тормоза в Qt IO Отправлено: pastor от Июль 29, 2009, 14:57 Сделать самому замеры. Какой аналог StopWatch есть в Qt? Можешь использовать qDebug() + QTime::start\elapsed Название: Тормоза в Qt IO Отправлено: Winstrol от Июль 29, 2009, 16:43 Под .net ещё пробовал читать полностью в память, потом разбирать - медленно и большие затраты памяти (весь файл мне не нужен). Это самый быстрый способ. Cмотреть на memory mapped fileВыйгрышный вариант оказался читать, пропускать. Я бы с радостью и не читал по одному float, но надо делать пропуски. 150 метров должно по одном float'у читаться за твое время. Если пропускать, должно быть быстрее. Что-то у тебя не то.Пробовал и через seek, накладно на небольших отступах. Цитировать Посмотрел в src: read читывает в 4kb буффер. Это немного. Желательно читать в больший буфер в зависимости от структуры файла. И когда данные в файл пишешь, голову никто не отменял. Полезную информацию надо писать блоками, а не разбрасывать по файлу.Как можно отказатся от буферирования? Название: Тормоза в Qt IO Отправлено: romank от Июль 29, 2009, 20:11 Значит надо повторится специально для вас.
Приведенный ранее код C# характерен: пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было. Дефолтное считывание по 4kb, как вообще было понятно из обсуждения, видимо не так хорошо в моём случае. Хотя не было утверждения об обратном. Про голову хорошо написано, только не понятно зачем. Не все форматы файлов придуманы (к сожалению) мной и порой приходится читать как дают, а не как хочется, в соответствии с technical description. Поэтому как-то с сомнением отношусь к вашей рекомендации. Но всё равно спасибо. Название: Тормоза в Qt IO Отправлено: Winstrol от Июль 29, 2009, 22:23 Значит надо повторится специально для вас. Ну, тогда другое дело. Должно работать быстро. Нужно делать замеры времени работы различных участков кода Приведенный ранее код C# характерен: пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было. хотя бы с помощью clock() из <time.h>, чтобы понять, где тормозит. Название: Тормоза в Qt IO Отправлено: Tonal от Июль 30, 2009, 07:26 пропуск 54 байт...считывание 75 + 75 байт...пропуск 12...считывание 100 и так далее. О чтении 150 метров (а то и ~1Gb) по float за раз, разговора и не было. Чтобы отключить буферизацию, нужно добавить флаг QIODevice::Unbuffered при открытии.Дефолтное считывание по 4kb, как вообще было понятно из обсуждения, видимо не так хорошо в моём случае. Хотя не было утверждения об обратном. Хотя тот порядок считывания, что ты привёл довольно нормально ложится в буфер 4кб - ведь большинство чтений из буфера. Короче профилировать нужно а не пальцем в небо тыкать. :) Название: Тормоза в Qt IO Отправлено: romank от Июль 30, 2009, 07:42 Ваше "короче профелировать надо" и "нужно делать замеры времени" было предложено за день. Пальцем в небо нет не тыкал, даже не понимаю к чему это относится.
Вообще мною получены практически все рекомендации и советы, последние сообщения излишне. Спасибо всем. Название: Тормоза в Qt IO Отправлено: Tonal от Июль 30, 2009, 10:32 Главные советы - учить язык и читат Ассистента тебе вроде здесь ещё никто не давал.
А по твоиму коду и вопросам они таки напрашиваются. :) Да, Qt - это библиотека а не язык или платформа. Поэтому "профиляторов под Qt" ты не найдёшь. :) Искать нужно профилятор под тот компилятор, на котором работаешь. :) В мингве, как и в gcc для этого используется опция -pg и тулза gprof П.С. 2 Moderators Предлогаю вынести разделить топик. Начиная с поста #24 (http://www.prog.org.ru/index.php?topic=9876.msg59999#msg59999) вынести в отдельную тему "Тормоза в Qt IO". Название: Re: Тормоза в Qt IO Отправлено: romank от Июль 30, 2009, 11:36 Я не знаю конечно, где в моем коде вопиющее незнание языка.
Обычный код, обычные вопросы. Ассистента читать умею. И на гугле не забанен ! Те кто отвечал вначале, понимают о чем вопрос. Те кто отвечают в конце с трудом понимают в чем вообще дело. Причем здесь "Да Qt это библибиотека" и так далее. Ясно же о чем спрашивал. Не надо никаких "Тормоза в Qt", Qt не тормозит. Надо переименовать в " Qt. Fast read binary file" Название: Re: Тормоза в Qt IO Отправлено: Alex Custov от Июль 30, 2009, 13:44 пиши только так: char m_buffer[sizeof(float)]; Стоит упомянуть, что VLA (http://en.wikipedia.org/wiki/Variable-length_array) в C++ доступны только как расширение GCC. Название: Re: Тормоза в Qt IO Отправлено: BRE от Июль 30, 2009, 13:52 пиши только так: char m_buffer[sizeof(float)]; Стоит упомянуть, что VLA (http://en.wikipedia.org/wiki/Variable-length_array) в C++ доступны только как расширение GCC. Название: Re: Тормоза в Qt IO Отправлено: Winstrol от Июль 30, 2009, 15:00 Стоит упомянуть, что VLA (http://en.wikipedia.org/wiki/Variable-length_array) в C++ доступны только как расширение GCC. Теперь уже наверное не расширение, а поддержка C99. У Intel C++ тоже есть.Название: Re: Тормоза в Qt IO Отправлено: Tonal от Июль 31, 2009, 12:27 Вы спрашивали, мы отвечаем! :)
Я не знаю конечно, где в моем коде вопиющее незнание языка. Ответ #5 (http://www.prog.org.ru/index.php?topic=10181.msg60037#msg60037), первый фрагмент С++:Непонимание отличий от управляемых языков в работе с памятью. Использование "магических констант" вместо sizeof. Использование "приведения в стиле С" вместо reinterpret_cast. Ассистента читать умею. И на гугле не забанен ! Ответ #5 (http://www.prog.org.ru/index.php?topic=10181.msg60037#msg60037), второй фрагмент С++:Использование read вместо seek. Ответ #13 (http://www.prog.org.ru/index.php?topic=10181.msg60277#msg60277) Ненайти константы отключения буферизации файла при открытии... Причем здесь "Да Qt это библибиотека" и так далее. Ясно же о чем спрашивал. Ответ #9 (http://www.prog.org.ru/index.php?topic=10181.msg60246#msg60246)Вопрос совершенно бессмысленен. Я, например, в основном пишу на Python + PyQt. Что тебе может дать мой корректный ответ использовать стандартный python-овский профилер? :) Что же касается тормрзов при чтении, то общий совет читать большими буферами, а потом из них уже восстанавливать нужные структуры в памяти. Идеально если структуры файла фиксированной длинны - тогда читаем буфер в несколько длинн записи. Если нет - читаем чтобы вместилось например от 10 до 100 или от 100 до 1000 записей. Т.к. чтение с диска самая затратная операция, то и выигрышь получаем соответственный. :) Тут нормально подойдёт отображение в память, только нужно учитывать, что система отображает тоже с какой-то гранулярностью, например 4к или 64к. Поэтому, по хорошему, размер отображения должен быть кратен этой гранулярности. :) Название: Re: Тормоза в Qt IO Отправлено: romank от Июль 31, 2009, 14:07 Это что обвинение на которое я должен дать ответ?
Если быть серьезным: cpp это не первый мой язык, я начинал с обычной (когда-то) цепочки basic->asm (Z80), потом универский pascal который перерос в delphi, далее C# и сейчас C++, читаю но не пишу на FORTRAN. Но программирование не стало моей основной работой, я занимаюсь сейчас научной деятельностью (это нет не оправдание моему как говорится "плохому" коду. Сомневаюсь кто ещё лучше пишет : научный специалист в своей области, знающий досконально о чем пишет или абстрактный программист работающий по техзаданию за деньги). Так что я наверно достаточно понимаю отличия одного языка от другого. Каюсь не всегда достаточно интереса и времени для чтения "сахара" присущего языку. Можете не спрашивать меня про итераторы и паттерны программирования. Мне достаточно циклов, переходов, простых классов и классов предоставляемых языком (или фреймворком). Не важно насколько красива твоя программа если она не работает. Поверьте я знаю что делает sizeof, использование постоянной 4 не является чем то специальным. В 90% случаев использую sizeof, например: Код 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. Нет, так и бог с ним, без этого можно жить. То что вы пишете на питоне или не на питоне мне совершено не интересно. Всё что дальше написано уже было. Название темы "Тормоз..." и так далее придумал не я. Общие советы знаю. Нужен был человек имеющий схожую ситуацию, с работающим кодом, который потратил своё драгоценное время на "а давай попробуем вот так" или "а может быть вот это". Итак что в итоге. Вы рассказали что читали классиков и пишете на питоне. Эй, вы молодец ! Название: Re: Тормоза в Qt IO Отправлено: Tonal от Август 03, 2009, 07:56 Это что обвинение на которое я должен дать ответ? Это не обвинение - каждый пишет так, как ему больше нравится. :)Но по тому что и как написано можно с лёгкостью понять насколько профессиональный человек это писал. Думаю, что в своей области ты тоже с лёгкостью отличишь дилетанта от профи не особенно вчитываясь в написанное. :) Это собственно ко всяким sizeof и приведениям. :) А вот по поводу "сахора" ты ошибаешься. Сахар - это всяческие foreach-и проперти и LINQ. Те же параметры по умолчанию - тоже сахар. Но работа с памятью и сборка мусора - базовое отличие управляемых языков (C#, Python) от неуправляемых (С++, Delphi, FORTRAN, Asm). В управляемых у тебя нет прямого доступа к памяти и для чтения приходится извращатся как в BinaryReader. В неуправляемых ты просто читаешь файл в указанную область, что тебе и подсказали. :) По поводу read вместо seek - это преждевременная оптимизация. В данном случае она просто ухудшает читабельность кода, но не даёт никакого существенного выигрыша. :) Т.е. опять же - придирки к стилю. :) Про скорость - совет один - читай большими блоками и их уже разбирай. Т.е. собственная буферизация. Ну и профилирование реализации. :) Про профилятор - всё зависим от компилятора и операционки. Ежели ты под мингвой - есть стандартный (правда не гуёвый) Ежели под MSVC - то вроде есть в поставке начиная с про версий, есть Intel® VTune, есть AMD CodeAnalyst, есть AQtime. Все по разному платные. :) Ну и классиков читать всяко нужно и полезно! :) Название: Re: Тормоза в Qt IO Отправлено: romank от Август 03, 2009, 08:26 Qt4.5 + mingv + winxp.
Зачем же вы всё рассказываете мне про память, я прекрасно знаю и даже помню asm. Даже у классиков (пишу по памяти) начинается с перебора в цикле for и заканчивается while (*p++ == *v++). То есть работа с указателями это НЕ преждевременная оптимизация, а замена read на seek это преждевременная? Для меня работа с указателями больше затрудняет чтение листинга, чем read на seek. Про сахар так и писал, всякие linq foreach и др. требуют дополнительного времени для изучения, может быть не всегда оправданного. Профессионала от дилетанта можно отличить не по красивости кода, а по умению эстетического алгоритмического мышления. Каждому кто показал более красивые решения, я сказал своё спасибо. На сегодняшний день я отложил изменения в считывании файла - буфферирование и прочее сильно изменят код. Сейчас доработаю с opengl и вернусь к этой теме. До скорых встреч. Название: Re: Тормоза в Qt IO Отправлено: romank от Август 03, 2009, 12:19 !!!
После перезагрузки первый запуск дает 5000ms. Повторные запуски 109ms. Далее закрывая программу, открывая другие данные (примерно считано 2Gb данных) и наконец опять открывая первый пример те же 109ms. Оптимизация никакая не нужна. 109ms это отличный результат, но что происходит в первый раз при запуске Qt программ? Или у меня жесткий диск буфферизирует 2Gb? Чертовщина. Название: Re: Тормоза в Qt IO Отправлено: Tonal от Август 04, 2009, 08:48 Начиная с ХР-юши в винду встроен оптимизатор запуска программ. Ранее входил в состав утилит Нортона, если мне не изменяет склероз.
При первом запуске в сеансе он собираеат и сохраняет дополнительную инфу о проге и нужных её дополнительных модулях. Поэтому последующие запуски происходят существенно быстрее. Про оптимизацию: работа с указателями для чистого С - это естественная и стандартная работа. Там нет массивов и строк как таковых. Есть примитивные типы и области памяти. :) Хорошо знающий С человек читая while (*p++ == *v++); видит просто копирование строки - это идеома. Да и компилятор знает такие идеомы и вполне может соптимизировать в инструкции копирования строки, например. :) А вот в C# подобный код может быть нужен только для работы с внешними unsefe интерфейсами. Ведь в чистом шарпе нет областей памяти и работы с голыми указателями. Есть массивы и строки. Ты не занимаешься распределением памяти, но лишен низкоуровневых возможностей. :) Именно по этому увидев твой код, я предположил что ты не понимаешь различия моделей памяти. Вполне возможно просто не задумывался. :) П.С. http://www.opennet.ru/docs/RUS/gprof/ - хорошее описание стандартного профилера под gcc/mingw. П.П.С. Первый мой учитель по программированию говорил: Написать фортрановскую программу можно на любом языке! :) Он преподавал нам язык REFAL - это что-то среднее между функциональным и логическим программированием. :) Название: Re: Тормоза в Qt IO Отправлено: Авварон от Август 04, 2009, 09:08 Хорошо знающий С человек читая while (*p++ == *v++); видит просто копирование строки - это идеома. лично я вижу недоделанное сравнение в лучшем случаеНазвание: Re: Тормоза в Qt IO Отправлено: Tonal от Август 04, 2009, 10:44 Хм, действительно сравнение.
Хотя от копирования оно отличается только одним оператором. Глаз уже замылился на python-е. :) Название: Re: Тормоза в Qt IO Отправлено: spectre71 от Август 04, 2009, 13:05 Копирование:
while ((*p++ = *v++)); Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 10, 2010, 23:51 Так и не смог ничего сделать.
.net работает с файлами большого объема раза в два быстрее чем C++. Qt здесь не причем. Название: Re: Тормоза в Qt IO Отправлено: Авварон от Январь 10, 2010, 23:53 если учесть, что .net написан сам на с++...
и потом, ты же написал что всё ок после повторного запуска. Такой еще вопрос - в .нете и 1й запуск не тормозит? И код бы финальный увидеть Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 11, 2010, 15:15 В .net также первый запуск самый долгий, следующие моментальные.
Код выложить конечно могу, но без данных он будет бесполезен и вообще объемно для форума. Если интересно приватно покажу, может быть свежий взгляд подскажет что. Мнение толпы бесполезно. Название: Re: Тормоза в Qt IO Отправлено: ритт от Январь 11, 2010, 19:29 а весь код и не нужен. интересен код "читалки"...
Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 11, 2010, 20:10 Код
Название: Re: Тормоза в Qt IO Отправлено: Dendy от Январь 11, 2010, 20:32 Невооружённым глазом видно утечку в readString(). Пользуйтесь для этих случаев QVarLengthArray.
Название: Re: Тормоза в Qt IO Отправлено: xokc от Январь 11, 2010, 20:50 А все-таки почему отображение в файлов в память (memory mapped files) не попробовать? У меня на больших файлах (~1GB) давало существенный выигрыш. Тогда все эти почти все эти read превратятся просто в операции приведения типов указателей, а о проблеме медленных seek для коротких интервалов вообще забыть можно.
Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 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(); } Название: Re: Тормоза в Qt IO Отправлено: Авварон от Январь 11, 2010, 23:23 const int напиши и мелкомягкий тоже съест... долже по крайней мере
Название: Re: Тормоза в Qt IO Отправлено: Dendy от Январь 12, 2010, 00:02 Не может компилятор такое кушать, ибо размер массива во время компиляции не определён, следовательно неизвестно сколько откусывать стека. Специально для этого придумали QVarLengthArray.
Название: Re: Тормоза в Qt IO Отправлено: ритт от Январь 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) , что универсальнее и по аналогии... /*тэгом "код" пользоваться тоже лень :) */ Название: Re: Тормоза в Qt IO Отправлено: BRE от Январь 12, 2010, 01:07 Не может компилятор такое кушать, ибо размер массива во время компиляции не определён, следовательно неизвестно сколько откусывать стека. Специально для этого придумали QVarLengthArray. Может, это расширение GCC, попробуй сам.Про визуалы не скажу не знаю. Название: Re: Тормоза в Qt IO Отправлено: Dendy от Январь 12, 2010, 01:28 Что пробовать то? Покажите минимальный рабочий пример.
Название: Re: Тормоза в Qt IO Отправлено: BRE от Январь 12, 2010, 01:34 Что пробовать то? Покажите минимальный рабочий пример. Код
и g++ a.cpp Название: Re: Тормоза в Qt IO Отправлено: Dendy от Январь 12, 2010, 08:51 Действительно, откусывает стек динамически. Проверил в MinGW/GCC4.4.0. А как это соотносится со стандартом?
Название: Re: Тормоза в Qt IO Отправлено: BRE от Январь 12, 2010, 09:34 Действительно, откусывает стек динамически. Проверил в MinGW/GCC4.4.0. А как это соотносится со стандартом? http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Variable-Length.html#Variable-LengthНазвание: Re: Тормоза в Qt IO Отправлено: Dendy от Январь 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Мб мгновенно обернулась крешем приложения. Название: Re: Тормоза в Qt IO Отправлено: ilot от Январь 12, 2010, 10:26 Невооружённым глазом видно утечку в readString(). Пользуйтесь для этих случаев QVarLengthArray. можно еще использовать постоянный буфер. Буфер создается один раз, следовательно не нужно при каждом вызове выделять и освобождать память:Код: const size_t buffSize = 100; Мапится боюсь, размеры могут быть до 10Gb. Судя по описанию функции Код: uchar * QFile::map ( qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions ) Как справедливо заметил Константин, маленькие утилитарные функции нужно сделать подставляемыми. По технике: чтобы избежать опечаток и облегчить чтение/понимание кода, "магические" числа лучше заменить на целочисленные константы (const int ...). Название: Re: Тормоза в Qt IO Отправлено: ритт от Январь 12, 2010, 11:55 не-не-не, нафик мемсет...
Код
Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 12, 2010, 12:25 Да и зачем динамическое unsigned char* buff = new unsigned char[buffSize], если размер буфера заранее известен. QString::QString ( const QChar * unicode, int size ) я так понимаю уникод онли, не помогло. Внес все коррективы, видимо компилятор и так достаточно умен, прирост ноль. Трудно ловить точное время с IO.
Название: Re: Тормоза в Qt IO Отправлено: ритт от Январь 12, 2010, 12:36 ах, ну, да
return QString::fromUtf8(buff, len).trimmed(); Название: Re: Тормоза в Qt IO Отправлено: vaprele07 от Январь 12, 2010, 12:37 не стоит городить велосипед: QBuffer + QFile::map
Название: Re: Тормоза в Qt IO Отправлено: ритт от Январь 12, 2010, 12:50 и не может быть чтобы приросту было ноль...
смотрю далее: вместо read вполне можно пропускать по seek; while (file.pos() != file.size()) - довольно неоптимально, лучше заменить на while (!file.atEnd()) ; ну, и как уже было сказано ранее, сотня чтений по 4 байта (инт) затратнее одного чтения четырёхсот байт -> читай документацию по QBuffer (затем будешь читать в байтаррэй н байт, где н - размер твоего блока, завернёшь байтаррэй в буффер и подставишь буффер вместо файла (для этого мы заменили QFile на QIODevice ранее)) Название: Re: Тормоза в Qt IO Отправлено: ilot от Январь 12, 2010, 12:55 Да и зачем динамическое unsigned char* buff = new unsigned char[buffSize], если размер буфера заранее известен. Сам бы я определил отдельный класс для обработки файла, а все эти функции сделал его методами. Отсюда логично, чтобы память для буфера динамически выделялась в его конструкторе и освобождалась в деструкторе, а не заранее в статической области памяти. Собственно только из этих соображений...не стоит городить велосипед: QBuffer + QFile::map чем собственно плох метод? все естественно и лаконично.. Существующие решения не всегда самые лучшие в отдельно взятом случае. Тем более выше я писал, что нужно рассмотреть оба варианта и сравнить результат.Название: Re: Тормоза в Qt IO Отправлено: vaprele07 от Январь 12, 2010, 15:03 Мапируем или весь файл или нужную область (100 метров или 1гб) "QByteArray::fromRawData" в QBuffer и подставляем в проблемный код.
Хотя возможно я не понял задачу ??? Название: Re: Тормоза в Qt IO Отправлено: xokc от Январь 12, 2010, 20:38 Мапируем или весь файл или нужную область (100 метров или 1гб) "QByteArray::fromRawData" в QBuffer и подставляем в проблемный код. +100. Мапить можно не весь файл, а только часть его (чем больше - тем лучше) - на винде будет в разы быстрее работать.Хотя возможно я не понял задачу ??? Название: Re: Тормоза в Qt IO Отправлено: Tonal от Январь 13, 2010, 08:57 Если тебе не критично сохранить старый формат, то просто используй QDataStream. :)
Если таки критичен, то не забывай, что в С++ память нужно освобождать и работа с ней по выделению/освобождению несколько медленнее чем в шарпе. Код
Название: Re: Тормоза в Qt IO Отправлено: Tonal от Январь 13, 2010, 09:22 Ну и читать конечно нужно не по интику и фловтику а сразу блоком, который потом уже и разбирать. :)
Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 13, 2010, 10:29 Спасибо, всем ещё раз.
Да всё правильно, читать надо большим блоком и разбирать уже в памяти. Здесь частично такое используется за счет readInt32buffer, читаются небольшие буфера. Перейдем на мапинг, чего там. Интересно получается, предложенные рекомендации (в отдельный класс вынести чтение и другие) посадили производительность C# в ракету и запустили на Марс. Для С++ это всё полумеры, основное падение производительности связано именно со скоростью IO (скорость движения танковой колоны равна скорости движения самого медленного танка), поэтому все inline и прочие "оптимизации" памяти прироста не дают. Впечатление что .NET хоть и написан на C++ к файловой системе подходит с более нежной стороны, может в потрохах своих чего и мапит, ничего нагуглить не получилось. Принципиально хотелось сравнить как один и тот-же механизм работает на C++ и C#. Видимо писать здесь больше не о чем, поэтому скажу не по теме. В соседних ветках кто-то сравнивал .NET и Qt, у меня есть небольшой жопыт и там и там, что можно сказать. .NET я люблю за C#, но презираю за WindowForms, Qt я люблю за GUI, но ненавижу за C++. Больше всего C++ я ненавижу за перечисления !!! Если в C# писать под OpenGL это одно удовольствие, то под C++ это постоянное смотрение в superbible, а какие же там флаги на самом деле. Писали что Assistent лучше чем MSDN. Может быть и лучше, но количество обращений к документации в C++(Qt) намного больше чем к MSDN. C# (а наверно больше VS) имеет достаточные средства самодокументирования, нет необходимости прибегать к отдельным справочникам, многое о классе можно узнать из кода. Но вот скорость WindowForms это просто невозможно смотреть без боли. Я делал паузу в полгода чтобы дождаться выпуска .NET4.0, задумывался о WPF. И что получается. Под WinXP WPF уродлив, чтобы не говорили про возможности. Этот гребанный дрожащий фонт раздражает глаза, такая мелочь, но так неприятно. Именно за фонты я ненавижу и GUI+. Где мой родной cleartype который я не могу повторить в gui+, wtf? А за красоту и скорость можно полюбить и черта лысого. Поэтому, отставить колебания, упереться рогом и ползти. Благо есть интернет, есть src и есть вы - добрые и отзывчивые люди. Название: Re: Тормоза в Qt IO Отправлено: Авварон от Январь 13, 2010, 17:22 насчет мсдн - вы видимо не сильно извращались... дефолтные значения работают на ура - а скорми тому же фс вотчеру 3000 файлов и посмотри что будет. А потом натрави его на сетевой фолдер... и покажи мне место в мсдне где написано что с ним не так... я к счастью нашел... но программирование методо гугла не интересно:) В ассистанте, как правило нюансы все-таки описаны. Да в c++ многое более низкоуровнево и потому нетривиально на 1й взгляд. Но если подумать о том, как бы ты реализовыал сам, то многое становится на свои места:)
Название: Re: Тормоза в Qt IO Отправлено: xokc от Январь 13, 2010, 21:48 Впечатление что .NET хоть и написан на C++ к файловой системе подходит с более нежной стороны, может в потрохах своих чего и мапит, ничего нагуглить не получилось. Тут IMHO все довольно логично - MS строит новый интерпретируемый фреймворк, который жестко завязан на одну ОС, на него надо пересадить большое количество разработчиков - отсюда надо доказывать, что код .Net может быть производительнее УНИВЕРСАЛЬНОГО языка высокого уровня в случае работы, например, с файлами большого объема. Что бы делал я на месте разработчика .Net? В первую очередь, зная о существенном ускорении файловых операций для файлов больших размеров в Windows за счет mapping, при открытии такого файла тупо делал бы map. Для .Net разработчика этот механизм скрыт и существенная часть из них может просто сделать "логичный" вывод - ".Net быстрее C++".Название: Re: Тормоза в Qt IO Отправлено: romank от Январь 13, 2010, 23:17 Поэтому и задавал первый вопрос.
Tonal Код Это сработает, если строки zero-null terminated. В моем случае это не так Код Это фактически перевод из StringToInt. У меня четыре байта это не текст, это целочисленное или с плавающей запятой число. xokc под .net мне было достаточно скорости. Я вообще не знаком ни с одним программистом, но мне кажется что .net разработчик не глупее обычного. По крайне мере я знаком с file mapping(у Рихтера было разжевано), но никогда не использовал (это я пытаюсь оправдать себя). Под .net не скрыто, можно делать CreateFileForMapping и так далее. Понятно что я не могу покрывать сто процентов возможностей (сети и базы это мимо меня), но я не вижу никакой разницы между .net и qt. Везде я нахожу уже готовые полезные классы. Красивые оба. После прихода nokia qt стал ещё лучше. В чем плюс, точнее два плюса от cpp это разнообразие философии - ты можешь придумать свой круг понимания языка. Например, можно писать программы и без указателей. Можно (но недолго) без ООП. Я замыкаюсь в рамках qt-классов и пишу в стиле C#, если не смотреть на объявление классов а только на реализации - визуально разница в коде процентов 2-3% (немного по другому работа с массивами). Так что переход с C# на C++(Qt) весьма быстрый. Недавно писали что под C# надо писать в два раза больше кода. Ерунда, никакой разницы. Название: Re: Тормоза в Qt IO Отправлено: Tonal от Январь 15, 2010, 13:45 Это сработает, если строки zero-null terminated. В моем случае это не так Да, хотя это и странно - в QByteArray длинна присутствует явно. Тогда так.Код
Код Это фактически перевод из StringToInt. У меня четыре байта это не текст, это целочисленное или с плавающей запятой число. Здесь действительно локальная переменная будет правильно. :) Да, надеюсь ты тестируешь скорость не на отладочных версиях? Ну и насчёт писать больше/меньше - на С++ действительно можно писать меньше чем на C# если использовать его преимущества. :) Правда для этого его нужно таки знать. :) А если писать на С с классами, то действительно никакой разницы. |