LINUX.ORG.RU

Сравнение производительности Qt и Cairo


2

0

Зак Русин провел сравнение производительности векторной графики в Qt и Cairo. Тест состоит из рендеринга трех сложных полигонов: text path, маленький полигон с большим количеством вершин на одной линии, огромный полигон с количеством вершин порядка 100000.

Измерялось количество кадров в секунду, использовались версии Cairo 1.2.5 (XRender и Glitz), Amanith из svn, Qt 4.3 (XRender и OpenGL) на Pentium4 3.2ГГц, 1Гб, NVIDIA 6600 с драйвером 1.0-9625.

Все тесты использовали антиалиасинг, и были предприняты усилия, чтобы поставить библиотеки в равные условия. Результаты очень интересны:

* Qt быстрее Cairo в XRender в 5-7 раз
* Qt(OpenGL) быстрее Qt(XRender) в 5-7 раз, но упирается в производительность GPU при 80000+ вершин
* Cairo(Glitz) показывает одинаковую производительность с Cairo(XRender)
* Ни Amanith, ни Cairo(XRender) не могут справится с последним полигоном в 100000 вершин.
* С большим полигоном Cairo(Glitz) отображает 0.2 кадра в секунду, а Qt переваливает за 10 fps.
* Qt(XRender) на порядок превосходит по производительности и Cairo(Glitz), и Amanith, хотя последние работают с OpenGL ускорением, а первый без него.


Выводы: Qt на голову выше других библиотек, а в OpenGL настолько быстр, что сравнивать с чем либо ещё просто нечестно.


PS от автора новости: Остается надеяться, что OpenSource позволит авторам Cairo "подсмотреть" построение тесселятора и рендерера, чтобы сократить разрыв до приемлемых значений.

>>> Подробности

★★★★★

Проверено: Shaman007 ()

Ответ на: комментарий от anonymous

> так кто-же конструирует объект ? коструктор ? семантическая дырка в яве ?

Смотря что считать конструированием. Даже в плюсах часть работы по конструированию выполняется неявно (заполнение vtable). В жабе доступное программисту конструирование состоит из присвоения всех дефолтных значений (сначала), вызова последовательности конструкторов (потом). Чего Вам не хватает в этой модели?

svu ★★★★★
()
Ответ на: комментарий от svu

> А зачем в конструкторе делать move, Вам же нужно только построить автомобиль?

вы уже сказали - Ерраре гуманум ест. :)))) и, почему бы мне не перемещать автомобиль, при создании, в некоторое определенное место ?
а вы будете молиться что-бы я этого не делал :))))))

> Я же говорю - соглашения явы могут приводить к проблемам в некоторых случаях, но в реальности часто бывает наоборот, они скорее дают удобство

я уже говорил - такое поведение антипатерн, вне зависимости от языка,
было глобальное обсуждение, подключались "столпы"

> Возможно, это появилось после моего прощания с плюсами. Где почитать?

стандарт

> Что-то я потерял нить. Я правильно понял, что Вы хотите компилятором отслеживать вызовы виртуальных методов

нет, из родителя вызвать метод наследника

> Слово "указатель" у меня в кавычках. На самом деле - это переменные. Конечно, на уровне языка - никаких указателей. Так вот в стеке место только переменным, но никак не объектам.

правильно я вас понял - переменная это не объект ?

> В общем, тогда плюсы плавно перелезут в до-диез.

кажись другое название выбрали

anonymous
()
Ответ на: комментарий от svu

> Если у Вас ТАКОЙ ассемблер - тогда, конечно, он эквивалентен байткоду. Только старый добрый асм x86 вряд ли на эту роль сгодится...

не помню точно, MS кажись когда-то развлеклась - компилировала x86 в alpha, Sun развлекалась - компилировала x86 в sparc

anonymous
()
Ответ на: комментарий от svu

> Чего Вам не хватает в этой модели?

человек ошибся в определинии
есть инициализация, есть конструирование - это разные вещи

> выполняется неявно (заполнение vtable)

мммм, врядли, я бы даже сказал: нет такого языка который заполняет vtbl при инициализации объекта
мммм, у self другая модель, ...., вы не имеете же ввиду создание объекта класса ?

anonymous
()
Ответ на: комментарий от anonymous

> кстати, чем ассемблер не байт код ?

байт-код -- это уже обработанный ассемблер, но еще не бинарник

ЗЫ почитайте книгу по написанию компиляторов

vadiml ★★★★★
()
Ответ на: комментарий от anonymous

> а вы будете молиться что-бы я этого не делал

Не буду. Просто автомобиль придет туда с пустым прицепом (мы же помним, что так или иначе данные инициализируются до конструкторов). В любом случае - никто не умрет. Кстати, это ДЕЙСТВИТЕЛЬНО выглядит как ошибка дизайна - двигать автомобиль в конструкторе. Именно потому, что двигать недостроенный объект - глупо. А вот как в плюсовой модели сделать так, чтобы конструктор выводил окончательное название класса строящегося объекта? Без дублирования кода?

> было глобальное обсуждение, подключались "столпы"

Урлом не поделитесь?

> нет, из родителя вызвать метод наследника

Да, Вы таки меня потеряли в этом месте;)

> правильно я вас понял - переменная это не объект ?

Разумеется. Переменная это только способ доступа к объекту. Указатель на объект (не в сишном смысле, а в общечеловеческом). Одно из имен объекта, если хотите.

> кажись другое название выбрали

? Я опять все проспал?

svu ★★★★★
()
Ответ на: комментарий от anonymous

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

svu ★★★★★
()
Ответ на: комментарий от vadiml

В контексте нашей беседы их можно считать эквивалентными (хотя и не тождественными, само собой).

svu ★★★★★
()
Ответ на: комментарий от svu

> ЗЫ Не с г-ном ли Луговским имею честь беседовать?;)

Нет. Луговский не мог допустить таких ля... хм ошибок с конструкторами из Java и C#. У этих обоих языков конструкторы работают одинаково, чем, кстати, я имею удовольствие часто пользоваться.

Потом, ведь ниразу не прозвучали слова "лисп" и "выпей яду" :-)

SDE
()
Ответ на: комментарий от svu

> Не буду. Просто автомобиль придет туда с пустым прицепом (мы же помним, что так или иначе данные инициализируются до конструкторов)

Exception in thread "main" java.lang.NullPointerException
at B.x(B.java:7)
at A.<init>(A.java:7)
at B.<init>(B.java:8)
at Main.main(Main.java:8)

вы это имете ввиду ? боюсь что автомобиль никуда не придет

> Именно потому, что двигать недостроенный объект - глупо

только двигать ?

> А вот как в плюсовой модели сделать так, чтобы конструктор выводил окончательное название класса строящегося объекта? Без дублирования кода?

лучше конечно так - printDebug("my name")
(когда объект строится, то его имя и есть окончательное, переформулируйте вопрос)

> Урлом не поделитесь?
нет, давно очень было
поищите antipatterns

> Да, Вы таки меня потеряли в этом месте;)
мы говорили о разном (болтать так болтать)

> Указатель на объект (не в сишном смысле, а в общечеловеческом)
:)))))), значит на стеке то-же присутствуют только "общечеловеческие указатели - имена" :)))))

> ? Я опять все проспал?
не обратили внимания (это не название языка, рабочее название ....
я даже не знаю как это назвать, имя версии что-ли)

anonymous
()
Ответ на: комментарий от svu

А, я вот по нему скучаю. С ним можно было очень интересно о языках поспорить, конечно, если он не срывался на кого-нибудь. А если еще и int19h подключался...

---

SDE is just my another nickname

dave ★★★★★
()
Ответ на: комментарий от SDE

> У этих обоих языков конструкторы работают одинаково

не врите

public class X1
{
public X1 () { x ();}
public virtual void x () {Console.WriteLine("X1.x");}
}
public class X2: X1
{
public X2 () { x ();}
public virtual void x () {Console.WriteLine("X2.x");}
}
class Class1
{
[STAThread]
static void Main(string[] args){
X2 x = new X2();
}
}

output:
X1.x
X2.x

PS
соврали али нет ?


anonymous
()
Ответ на: комментарий от anonymous

Шикарно! У вас что-то там инициализируется null, а метод не умеет обращаться со значением null. Правая рука не знает, что делает левая...

> лучше конечно так - printDebug("my name") (когда объект строится, то его имя и есть окончательное, переформулируйте вопрос)

название КЛАССА. System.out.println(this.getClass().getName());

> не обратили внимания (это не название языка, рабочее название .... я даже не знаю как это назвать, имя версии что-ли)

Урл?

svu ★★★★★
()
Ответ на: комментарий от dave

Вот нестабильность и погубила Луговского. Срывался слишком часто;)

svu ★★★★★
()
Ответ на: комментарий от svu

> Шикарно! У вас что-то там инициализируется null, а метод не умеет обращаться со значением null. Правая рука не знает, что делает левая...

значит я должен знать особенности реализации предка ?
паранойя какая-то, во всех методах я должен проверять состояние, так как не уверен что меня не вызовут до конца конструирования

> КЛАССА. System.out.println(this.getClass().getName());
cout << typeid(this)->name();
переформулируйте вопрос - вы допустили ошибку

anonymous
()
Ответ на: комментарий от anonymous

А ты пробовал прогнать через компилятор?

------

Test.cs(12,22): warning CS0114: 'X2.x()' скрывает наследуемый член 'X1.x()'. Чтобы текущий член переопределял эту реализацию, добавьте ключевое слово override. В противном случае добавьте ключевое слово new.

Test.cs(6,22): (Местоположение символа относительно предыдущего предупреждения)

------

В общем, для метода X2.x() надо override поставить. Иначе методы X2.x() и X1.x() считаются несвязанными.

dave ★★★★★
()
Ответ на: комментарий от svu

Может быть, он имеет ввиду тот язык, о котором я уже как-то писал. Не помню что мы тогда обсуждали конкретно, кажется было тоже что-то вроде KDE vs GNOME :)

http://en.wikipedia.org/wiki/C++/CLI

dave ★★★★★
()
Ответ на: комментарий от anonymous

> значит я должен знать особенности реализации предка ?

Нет, Вы должны знать особенности своей собственной реализации.

> паранойя какая-то, во всех методах я должен проверять состояние, так как не уверен что меня не вызовут до конца конструирования

Если null не является валидным значением поля - инициализируйте его, пожалуйста, чем-нибудь более валидным:

public String name = "undefined";

Если является - извольте обрабатывать корректно в методе x. Чего уж проще?

cout << typeid(this)->name();

Что вернет typeid в конструкторе базового класса? Мне нужно имя _окончательного_ класса объекта.

svu ★★★★★
()
Ответ на: комментарий от vadiml

Эппл как раз в другую сторону работает;)

svu ★★★★★
()
Ответ на: комментарий от svu

> Нет, Вы должны знать особенности своей собственной реализации.

я знаю все о своей релизации, абсолютно все
знаю что после конструирования объект будет в валидном состоянии
знаю что использую поле только после его инициализации
не знаю только что конструктор предка вызывает мой метод.
должен знать ?

> Если null не является валидным значением поля - инициализируйте его, пожалуйста, чем-нибудь более валидным:

любой объект в начале null, так что ничего крамольного не вижу

> Если является - извольте обрабатывать корректно в методе x. Чего уж проще?

не является, у всех объектов этого типа это поле всегда должно быть проинициализированно, я сделал все что мог, что-бы так было

anonymous
()
Ответ на: комментарий от dave

>> В общем, для метода X2.x() надо override поставить.

_надо_ override или _надо_ new ?
почему определения, по умолчанию создают поведение не такое как в ява ?

anonymous
()
Ответ на: комментарий от anonymous

> почему определения, по умолчанию создают поведение не такое как в ява ?

ты правда думаешь, что я знаю ответ :) увы, но я не являюсь создателем c#...

dave ★★★★★
()
Ответ на: комментарий от anonymous

> знаю что использую поле только после его инициализации

Дык вот надо привыкнуть к тому, что поле _может_ использоваться после присвоения начального значения - до конструктора. Всего один единственный факт. Запоминается один раз, в процессе изучения жабы.

> любой объект в начале null

До присвоения начального значения. Еще раз: public String name = "undefined";

> у всех объектов этого типа это поле всегда должно быть проинициализированно

Инициализируйте валидными начальными значениями. Это вполне можно делать до конструктора.

svu ★★★★★
()
Ответ на: комментарий от svu

> Дык вот надо привыкнуть к тому, что поле _может_ использоваться после присвоения начального значения - до конструктора. Всего один единственный факт. Запоминается один раз, в процессе изучения жабы.

кошмарный язык, сплошное гадание на кофейной гуще
может - не может, и сплошная паранойя на тему постоянных if != null
при этом не понятно нужно ли это делать. не определенность и неэфективность заложенная в дизайн языка ....

> До присвоения начального значения. Еще раз: public String name = "undefined";
> Инициализируйте валидными начальными значениями. Это вполне можно делать до конструктора.

обратно частный случай ? когда существует валидное undefined
вы предлагаете писать на яве только настолько примитивные вещи ?

anonymous
()
Ответ на: комментарий от svu

>> cout << typeid(this)->name();
> Что вернет typeid в конструкторе базового класса? Мне нужно имя _окончательного_ класса объекта.

я не понимаю слово _окончательный_, давайте что-бы не разглагольствовать долго и упорно на эту тему пойдем через unit testing

есть
class A "находящийся" в модуле A.so
class B: public A "находящийся" в модуле B.so
class C: public A "находящийся" в модуле С.so

имя класса A - typeid(A).name()
имя класса B - typeid(B).name()
имя класса С - typeid(С).name()

какой assert(*****), в конструкторе A, должен выполнятся ?

anonymous
()
Ответ на: комментарий от dave

> ты правда думаешь, что я знаю ответ :) увы, но я не являюсь создателем c#...

в догонку, даже более того
вот тебе схема которую модифицировать каким либо словам-модификатором под ява поведение ты принципиально не сможешь
при этом явовский эквивалент с j# останется явовским

public interface I { void x (); }
public class X1:I { public void x () {Console.WriteLine("X1.x");}
public X1 () { x ();}
}
public class X2: X1,I { public void x () {Console.WriteLine("X2.x");}
public X2 () { x ();}
}

anonymous
()
Ответ на: комментарий от anonymous

Я не совсем понимаю, чего ты хочешь. Такие вещи должен знать любой, кто профессионально и много программирует на С# и Java :)

dave ★★★★★
()
Ответ на: комментарий от dave

добится что-бы человек сказал:
"да я был не прав, когда сказал: 'У этих обоих языков конструкторы работают одинаково, ...,'"

anonymous
()
Ответ на: комментарий от anonymous

Я хочу в конструкторе класса А ОДИН РАЗ написать некий код. Который в случае создания объекта B выводил бы "B". В случае "C" - выводил бы "C". Как это сделать? В жабе это сразу выдаст this->getClass()->getName() - потому что getClass сразу возращает конечный класс объекта.

svu ★★★★★
()
Ответ на: комментарий от anonymous

> кошмарный язык, сплошное гадание на кофейной гуще

Ага. Альтернатива - гадание на кофейной гуще, к чему приведет вызов виртуального метода. Пишу я метод XX (весь из себя финальный) и в нем вызываю метод YY (виртуальный). И вот теперь я должен думать тяжку думу - что же случится, если не дай бог вызовут мой XX из конструктора.. Подход жабы это неопределенность данных, определенность вызовов. Подход плюсов - ровно наоборот.

> вы предлагаете писать на яве только настолько примитивные вещи ?

Всякая сложная вещь в процессе разработки распадается на множество простых. Приведите плиз пример, когда инициализация таким способом невозможна?

svu ★★★★★
()
Ответ на: комментарий от anonymous

Готов еще раз повторить. :-)

Логика поведения конструкторов в языках Java и C# совершенно одинаковая. _Полиморфизм_ работает в отличие от.

P.S. Ни в одном из твоих примеров не было двух связных полиморфизмом методов. В Java два метода с одним именем связываются _автоматически_ по определению. В C# это надо делать _руками_, т.е. прописывать override.

P.P.S. (измученным голосом) Наконец-то, прочитай какой-нибудь учебник...

dave ★★★★★
()
Ответ на: комментарий от anonymous

В этом примере классы X2 и X1 дают две _разные_ реализации одного и того же интерфейса I (особенность .NET). Полиморфизма нет, и метод X2.x() не связан с методом X1.x().

P.S. Все-таки возьмись за учебники...

dave ★★★★★
()
Ответ на: комментарий от svu

>> Я хочу в конструкторе класса А ОДИН РАЗ написать некий код. Который в случае создания объекта B выводил бы "B". В случае "C" - выводил бы "C". Как это сделать? В жабе это сразу выдаст this->getClass()->getName() - потому что getClass сразу возращает конечный класс объекта.

assert(class_name() == "B" || class_name() == "C") ?

anonymous
()
Ответ на: комментарий от svu

>> вот теперь я должен думать тяжку думу - что же случится, если не дай бог вызовут мой XX из конструктора..

>> Подход жабы это неопределенность данных, определенность вызовов. Подход плюсов - ровно наоборот.

подход явы - неопределенность данных и неопределенность вызовов
подход плюсов - определенность данных и определенность вызовов


PS
я не хочу больше спорить, по вашим высказываниям видно - вы уже почти сказали "подход явы - неопределенность данных и неопределенность вызовов", у меня есть работа, болтовня прекращается

anonymous
()
Ответ на: комментарий от svu

> Приведите плиз пример, когда инициализация таким способом невозможна?

когда тип поля требует для инициализации данные доступные только из конструктора, или из контекста конструирования .... дальше продолжайте сами

anonymous
()
Ответ на: комментарий от anonymous

Какой assert на имена B и C в конструкторе класса А????? И, кстати, что вернет class_name() в конструкторе класса А?

svu ★★★★★
()
Ответ на: комментарий от anonymous

> подход плюсов - определенность данных и определенность вызовов

Возьмите себя в руки! Какая же, блин, "определенность вызовов", если код this->my_method() вызывает разные функции в зависимости от того, что у нас лежит в стеке к моменту вызова?? У одного и того же объекта!

> по вашим высказываниям видно

Что-то у Вас со зрением;)

Удачной работы, однако.

svu ★★★★★
()
Ответ на: комментарий от anonymous

Дефект дизайна? Хотя если такая беда случилась - да, придется таки мучаться - либо проверять на null везде, либо просто быть уверенным в том, что происходит в конструкторах базовых классов. Увы.

svu ★★★★★
()
Ответ на: комментарий от dave

>
"Готов еще раз повторить. :-)
Логика поведения конструкторов в языках Java и C# совершенно одинаковая. _Полиморфизм_ работает в отличие от.
P.S. Ни в одном из твоих примеров не было двух связных полиморфизмом методов. В Java два метода с одним именем связываются _автоматически_ по определению. В C# это надо делать _руками_, т.е. прописывать override.
P.P.S. (измученным голосом) Наконец-то, прочитай какой-нибудь учебник...
В этом примере классы X2 и X1 дают две _разные_ реализации одного и того же интерфейса I (особенность .NET). Полиморфизма нет, и метод X2.x() не связан с методом X1.x().
P.S. Все-таки возьмись за учебники...
"

я плохо знаю c# и java - новичек
зато выяснил точно - в с# можно преодолеть явовскую шизофрению :)))
!но, замете, даже обладая малым количеством знаний о яве или c#, даже ругая шизофреничный подход к конструированию я ниразу не назвал java - недоОО

anonymous
()
Ответ на: комментарий от svu

>> возьмите себя в руки! Какая же, блин, "определенность вызовов", если код this->my_method()

можете считать что конструктор это псевдофункция в которой vtbl не доступна, это очень определенная вещь (в яве же на стеке лежат необъекты :)

>> вызывает разные функции в зависимости от того, что у нас лежит в стеке к моменту вызова??

почему вы решили что на стеке будет лежать вышестоящий конструктор ?
компилятор может раскрыть new Object схематично в { void* place = malloc(sizeof(Object)); new (place) P1; new (place) P2 ... }



anonymous
()
Ответ на: комментарий от svu

> Какой assert на имена B и C в конструкторе класса А????? И, кстати, что вернет class_name() в конструкторе класса А?

вы уже поняли в чем проблема ?

anonymous
()
Ответ на: комментарий от svu

> Что-то у Вас со зрением;)

с неопределенность данных вы согласились ...
написали: "И вот теперь я должен думать тяжку думу - что же случится, если не дай бог вызовут мой XX из конструктора.. "

не знаю как можно думать о том, что можно знать определенно.
зачем вы думаете если вы знаете ?

anonymous
()
Ответ на: комментарий от dave

> предлагаю закругляться - Он просто нас не слышит... :(

я так-же могу сказать что вы меня не слышите

anonymous
()
Ответ на: комментарий от anonymous

Я давно понял. Только это проблема плюсов! Что class_name в конструкторе возвратит что-то, что к реальному классу объекта отношения не имеет (точнее, относится как родительский класс).

svu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.