با سلام در این پست قصد دارم توضیحی در مورد QtQuick Custom Item Performance بدم و بعد نقدی بر روش استفاده از ساخت ایتم از سی پلاس پلاس برای کیو ام ال داشته باشم .

در این پست توضیح داده که اگر بخوایم یک ایتم کاستوم بکشیم سه راه پیش رو داریم و بعد به روش های زیر اشاره کرده :

  1. کشیدن با استفاده از اوپن جی ال و QQuickItem ( یا استفاده از یک ایتم داخلی )

  2. کشیدن با استفاده از QPainter و QQuickPaintedItem

  3. کشیدن با canvas

ولی قبل از شروع این موضوع ترجیه میدم یک توضیح در مورد سناریو طراحی گرافیکی دو بعدی داشته باشم .

در کیوت و ویجت ها Graphics View Framework رو داریم که روند کلی و معماریش بر این اساس هست که به ترتیب از بالا یک QGraphicsView داریم که براش یک QGraphicsScene تنظیم می‌کنیم و توی این Scene ما میتونیم QGraphicsItem های خودمون که اشکال دو بعدیمون هستند رو اضافه می‌کنیم و نمایش میدیم .

این سناریو توی تقریبا همه حالت‌های طراحی دو بعدی داریم .

و اما توضح در مورد تست  در این پست توی این پست اومده از یک ابجکت داخلی کیو ام ال یعنی Rectangle این کار رو کرده یعنی اومده در چند مرحله با اعداد مختلف یک حالت رو تست کرده در یک مرحله اومده با ریپیتر 10 هزار تا مربع با اندازه 4×4 درست کرده که البته چون روی هم افتادند فقط یکیشون قابل نمایش هست و توی مرحله بعد ابعاد رو کرده 64×64 و با همون تعداد 10 هزارتا انجام داده کار رو و در مرحله آخر اندازه رو کرده 512×512 ولی تعداد رو ده برابر کمتر کرده و نتایج رو منتشر کرده که به صورت زیر هستند :

تست با اندازه 4x4 و تعداد 10000 :

  • QtQuick OpenGL 31 fps
  • QQuickPaintetItem 10.4 fps
  • Canvas 1.0 fps

نتایج تست با اندازه مربع 64x64  و تعداد 10000 :

  • QtQuick OpenGL 31 fps
  • QQuickPaintetItem 4.2 fps
  • Canvas 2.2 fps

نتایج تست با اندازه مربع 512x512 و تعداد 1000 :

  • QtQuick OpenGL 18 fps
  • QQuickPaintetItem 1.2 fps
  • Canvas 1.2 fps

و اما مشکلی که در این روش هست اینه که توی کیو ام ال هر ایتم Scene اختصاصی خودش رو داره و همین باعث میشه که ایجاد 10 هزار ایتم توی کیو ام ال کلا کار درستی نباشه در واقع اگر به سناریو همون Graphics View Framework برگردیم مثل این هست که به ازای هر ایتم یک QGraphicsView درست کنیم و براش یک QGraphicsScene تنظیم کنیم و توی اون فقط یک QGraphicsItem نشون بدیم و در واقع از هرکدوم از این سه ابجکت ده هزار تا داریم که اصلا بهینه نیست .

معماری درست به این شکل هست که وقتی تعداد زیادی ایتم برای نمایش داریم همه رو توی یک View و توی یک Scene نشون بدیم و تعدد فقط روی ایتم ها باشه ولی این توی کیو ام ال و با ایتم های عادی امکان پذیر نیست مگر با Canvas که این مورد هم چون سمت جاوا اسکریپت هست و تفسیری هست اصلا پرفورمنس خوبی نداره بنابراین راهی که پیش پا میمونه استفاده از QQuickItem هست ولی نه به این روشی که ایشون انجام داده .

من همین اومدم 10 هزار تا مربع رو در کنار هم نمایش دادم و البته اندازه هاشون رو گذاشتم 512 یعنی ده برابر مورد اخر تست پست بالا و جالب این بود که وقتی بجای کیو ام ال ایجاد مربع ها رو بردم سمت کیو ام ال و بجای هر مربع دوتا مثلث کشیدم (در واقع 20 هزار شکل گرافیکی ) و یا میشه گفت 10 هزارتا مربع و تونستم به 72 fps دست پیدا کنم یعنی با ده برابر ایتم گرافیکی بیشتر تونستم به 4 برابر fps تست پست بالا دست پیدا کنم .

من  در ابتدا کد های پست بالا رو کردم یک پروژه و بعد سناریو خودم رو روش پیاده کردم و الن پروژه کامل رو براتون منتشر می‌کنم . در صورتی که خواستید سناریو پست بالا رو تست کنید کافیه توی کیو ام ال بخشی که بالاش براتون نوت گذاشتم رو کامنت کنید و بخش پایینش رو که باز براتون کامنت گذاشتم از کامنت در بیارید و عدد solution رو توی همون فایل کیو ام ال تغییر بدید تا هر سه حالتی که بررسی کرده رو تست کنید . راستش رو بخواید نخواستم بیش از ان وقت بذارم و این روند رو خودکار کنم تا همه سناریو ها بدون تغییر کد قابل بررسی باشند .

 

لینک پروژه در Github