Была у меня функция, выводящая полилинии, алгоритм примерно такой:
void DrawMyPolylines()
{
for(int i=0; i<NUMBER_OF_LINEAR_OBJECTS; i++) // несколько тысяч
{
// создание данных для группы ломаных, преобразование координат
//...
// выбор пера (толщина, цвет) для группы ломаных...
SelectObject(перо);
PolyPolyline(Группа полилиний);
}
}
Опытным путем я выяснил, что огромное количество полилиний рисуется всего несколькими видами перьев.
Поэтому я, с целью сократить количество вызовов PolyPolyline(), сгруппировал данные по перьям. Теперь PolyPolyline, вместо несколько тысяч раз, вызывается десяток раз, но с большим объемом данных.
Результат меня удивил — стало в 5 раз медленнее. Причем я измерил — это не накладные расходы на группировку.
В чем тут подвох?
Здравствуйте, dmitry_npi, Вы писали:
_>Была у меня функция, выводящая полилинии, алгоритм примерно такой:
_>Опытным путем я выяснил, что огромное количество полилиний рисуется всего несколькими видами перьев. _>Поэтому я, с целью сократить количество вызовов PolyPolyline(), сгруппировал данные по перьям. Теперь PolyPolyline, вместо несколько тысяч раз, вызывается десяток раз, но с большим объемом данных.
_>Результат меня удивил — стало в 5 раз медленнее. Причем я измерил — это не накладные расходы на группировку. _>В чем тут подвох?
а ты не замерял точное время, которое занимает вызов? было бы интерестно посмотреть как оно зависит от количества точек/полилиний (линейно? как степенная функция?).
похоже на то, что там используется какой-то алгоритм с полным перебором точек например.
кроме того, насколько я понимаю, эта функция может зависеть от видеодрайвера. интерестно было бы проверить на машинах с разными видяхами. так же будет скорость проседать?
best regards, Leonid
Re: Рисование полилиний на GDI
От:
Аноним
Дата:
15.07.10 12:52
Оценка:
Здравствуйте, dmitry_npi, Вы писали:
_>В чем тут подвох?
Наверное в том, что на CreatePen и DeleteObject
экономить нет смысла
Здравствуйте, Аноним, Вы писали:
А>Наверное в том, что на CreatePen и DeleteObject А>экономить нет смысла
Вовсе нет. Но на этом я уже сэкономил раньше, создав пул перьев, и выиграл процентов тридцать. А теперь хотел попытаться сэкономить на вызовах (переключение контекста и все такое). Я ожидал, что будет, по крайней мере, не медленней.
Здравствуйте, waveable, Вы писали:
W>а ты не замерял точное время, которое занимает вызов? было бы интерестно посмотреть как оно зависит от количества точек/полилиний (линейно? как степенная функция?). W>похоже на то, что там используется какой-то алгоритм с полным перебором точек например. W>кроме того, насколько я понимаю, эта функция может зависеть от видеодрайвера. интерестно было бы проверить на машинах с разными видяхами. так же будет скорость проседать?
Пока таких детальных измерений не проводил. Но, видимо, все равно придется отказаться от GDI... А жаль, он такой простой...
В GDI нет контекста как в 3D. GDI просто передаёт данные в драйвер и тот уже рисует, причём все атрибуты карандаша разворачиваются и приходят сразу. Ну и скорей всего всё это в памяти а не в карте происходит.
Для примера посмотрите в MSDN, DrvStrokePath, параметр LINEATTRS. Мне кажется, что не стоит объединять данные для PolyLine.
Видимо данные становятся большими и сложными, и система тратит много времени на создание временных буферов под уже трансформированные точки и т.д.
Надо просто найти баланс, сколько можно объединять за раз, если вообще надо.