جستجو در تالارهای گفتگو
در حال نمایش نتایج برای برچسب های 'بهینه سازی'.
1 نتیجه پیدا شد
-
کامبیز اسدزاده یک موضوع را ارسال کرد در <span class="ipsBadge ipsBadge_pill" style="background-color: #2cdb89; color: #000000;" >کتابخانه کیوت (Qt)</span>
پیشنهادات و ملاحظات در عملکرد و کارآیی همانطور که میدانید تولید و توسعهی یک نرمافزار با سرعت و کارآیی بالا یکی از مزایایی مهارتی توسعهدهندگان است که به تنهایی میتواند به عنوان یک فاکتور بسیار مهم مطرح شود. بنابراین در صورتی که شما محصولی را در قالب وب، موبایل یا دسکتاپ تولید میکنید باید به آن توجه داشته باشید که سرعت اجرایی برنامهی شما در زمان استارتاپ و بعد در مراحل پردازشی و فرایندهای دیگر باید مورد قبول باشد. در این میان برنامهنویسان سی++ میدانند که باید در مدیریت حافظه و دیگر موارد با دقت بیشتری عمل کنند تا بتوانند به حداقل نشتی در حافظه (حتی فاقد نشتی در آن) و در نهایت رسیدن به حداکثر سرعت پردازشی توجه داشته باشند. با توجه به این موضوع که کتابخانهی Qt به عنوان یکی از کتابخانههای این زبان بشمار میآید؛ بسیاری از توسعهدهندگان درگیر توسعهی بخش فرانتاِند نیز میشوند. بنابراین باید توجه داشت در زمان توسعه رابط کاربری مبتنی بر فناوری Qt Quick مواردی را جهت افزایش کارآیی سرعت و هماهنگی کامل با سی++ را در نظر بگیرند چرا که بدون در نظر گرفتن فاکتورهای زمانی نتیجهی آن بسیار بد خواهد بود. شما به عنوان یک توسعه دهنده نرمافزار، باید برای رسیدن حداکثر فریم ریت ۶۰ در موتور رندرینگ تلاش کنید. این میزان بدین معنی است که بین هر فریم که در میان آنها میتواند پردازش انجام شود، تقریباً ۱۶ میلی ثانیه وجود دارد که شامل پردازش مورد نیاز برای بارگذاریهای اولیه به سمت سختافزار گرافیکی میباشد. در عمل، این به این معنی است که توسعهدهنده نرمافزار باید: هر کجا که ممکن است از روش ناهمزمان (Asynchronous) در بخش برنامهنویسی رویدادمحور (Event-driven programming) استفاده کند. در بخشهایی که به میزان قابل توجهی شامل پردازش میشوند از وُرکرترد (worker threads) استفاده کند. هرگز حلقه رویداد را به صورت دستی برای چرخش و ادامه تنظیم نکند. هرگز بیش از چند میلی ثانیه برای هر فریم در بلوک توابع صرف نکند. عدم انجام این کارها باعث پَرش در فریمها میشود که تاثیر بسیار جدی در تجربه کاربری دارد. نکته: الگویی که وسوسه انگیز است اما نباید هرگز از آن استفاده شود، چرا که یک متد QEventLoop و یا صدا زدن یک متد دیگر مانند QCoreApplication::processEvent به منظور جلوگیری از مسدود شدن در یک بلوک کُد سی++ که در QML استفاده شده است به کار گرفته میشود. این خطرناک است، زیرا زمانی که یک حلقه رویداد در هندلر سیگنال و یا پیوند (Binding) وارد میشود، موتور QML همچنان برای اجرای سایر پیوندها، انیمیشنها، ترنسیشنها و غیره میپردازد. این اتصالات میتوانند باعث عوارضهای جانبی شوند. پروفایلینگ (Profiling) مهمترین نکته این است که: از ابزار QML Profiler که بخشی از محیط توسعه یکپارچهی نرمافزار Qt Creator است استفاده کنید. زیرا دانستن زمانی که در یک برنامه صرف میشود به شما امکان این را میدهد تا بر قسمت یا بخشی که در آن مشکل وجود درد تمرکز سریعتر و بهتری داشته باشید. برای نحوهی استفاده از این ابزار به کتابچهی راهنمای خود کیوت کریتور مراجعه کنید. تعیین کردن اینکه اغلب کدام پیوند (اتصال) در حال اجرا است، یا کدام یک از توابع شما بیشترین زمان را برای اجرا صرف میکنند، به شما این امکان را میدهد که تصمیم بگیرید که آیا شما نیاز به بهینه سازی آن بخش از کُدها را دارید یا نیاز خواهد بود آن بخش از کد خود را مجددا پیاده سازی کنید تا عملکرد آن بهتر شود یا خیر. به طور کلی تلاش برای بهینه سازی بدون استفاده از ابزار QML Profiler احتمالاً باعث بهبودهای جزئی و غیرقابل توجه در عملکرد خواهد شد. کُد جاوا اسکریپ (JavaScript) بیشتر برنامههای QML مقدار زیادی از کدهای جاوا اسکریپت در درون خود خواهند داشت. که به شکل توابع پویا، مدیریت سیگنال و یا عبارتهای مربوط به پراپرتیها (مشخصه، اموال) را در اختیار دارند. به طور کلی این یک مشکل نیست. با تشکر از برخی از بهینه سازیهای موتور QML، مانند آنهایی که به کامپایلر منتقل میشوند، میتواند (در بعضی موارد استفاده شده) حتی سریعتر از فراخوانیهای سمت سی++ باشد. با این حال، باید اطمینان حاصل شود که پردازش غیر ضروری به طور تصادفی اتفاق نیفتاده باشد. اتصالات (Binding) دو نوع اتصال در QML وجود دارد: اتصالات بهینه شده و غیر بهینه شده. ایدهی خوبی است که عبارات مربوطه را به همان اندازه سادهتر حفظ کنید. زیرا موتور QML برای ارزیابی عبارات از یک ارزیابی ساده و بهینه شده استفاده میکند که میتواند مشخص کند تا نیازی به تغییر آن در محیط جاوا اسکریپت نباشد. این اتصالات بهینه سازی شده بسیار کارآمدتر از اتصالات پیچیده تر (غیر بهینه سازی شده) هستند. الزامات اساسی نیز برای این گونه اتصالها این است که اطلاعات نوع هر نماد که به آن دسترسی دارد باید در زمان کامپایل شناخته شده باشد. عواملی که باعث جلوگیری از به حداکثر رساندن بهینه سازی در عبارات اتصالات میشود: تعریف متغیرهای واسط توسط جاوا اسکریپت دسترسی به خواص var صدا زدن توابع جاوا اسکریپت ساخت (آغاز یا خاتمه یافتن) و یا تعریف توابع در میان عبارت اتصالات دسترسی به خواص (پراپرتیهای) خارج از محدوده ارزیابی فوری نوشتن درمورد سایر عوامل به عنوان عوارض جانبی توجه داشته باشید، زمانی اتصالات سریعتر میشوند که نوع اشیاء و خواصی که با آنها کار میکنند مشخص شده باشند. این به این معنی است که، خواص غیرنهایی (non-final) ممکن است در بعضی موارد کُندتر باشد. (جایی که ممکن است یک خاصیت تغییر کرده باشد). محدودههایی ای که برای ارزیابی فوری میتوان در نظر گرفت قسمت زیر هستند: ارزیابی در خاصیت عبارتهای دامنهی یک شیء (برای عبارتهای اتصال، این است که شیء به کدام یک از خاصیتهای اتصال تعلق دارد). ارزیابی در شناسههای هر یک از اشیاء موجود در کامپوننت (جزء) ارزیابی در خاصیتهای ریشهی آیتم در یک کامپوننت (جزء) شناسههای اشیاء از دیگر کامپوننتها و خاصیتهای هر یک از اشیاء، مانند نمادهای تعریف شده و یا وارد شده از طرف جاوا اسکریپت در محدوده ی ارزیابی فوری نیستند. به این ترتیب اتصالاتی که به این موارد مربوط هستند نمیتوانند بهینه سازی شوند. نکته: توجه داشته باشید که اگر نمیتوانید اتصالات مورد نظر خود را توسط موتور QML بهینهسازی کنید، در این صورت باید آن را در محیط کامل جاوا اسکریپت بهینه سازی نمایید. نوع تبدیل (Type-Conversion) یک مزیت عمده برای استفاده از جاوا اسکریپت این است که در اغلب موارد، هنگامیکه به یک ویژگی از نوع QML دسترسی پیدا میشود، یک شیء جاوا اسکریپت با منبع حاوی سیپلاسپلاس پایه (یا یک مرجع آن) ایجاد میگردد. در بیشتر موارد، این عمل بهنسبت کمهزینه است، اما در سایر موارد میتواند بسیار پرهزینه باشد. یک مثال از پرهزینه بودن آن، ارجاع کردن QVariantMap و Q_PROPERTY به ویژگی نوع QML است. لیستها نیز میتوانند هزینهبالایی داشته باشند. اگرچه دنبالهی انواع خاص (QList از int، qreal، bool، Qstring و QUrl) باید کمهزینه باشد. تبدیل انواع دیگر لیست هزینهی زیادی دارد (ایجاد آرایهی جدید جاوا اسکریپت و افزودن تک به تک انواع جدید، با تبدیل هر نوع از نمونهی نوع سیپلاسپلاس به مقدار جاوا اسکریپت). رفع سازی خواصها تفکیک پذیری در خواص (پراپرتیها) زمان بر است. در حالی که در بعضی از موارد نتیجه آن میتواند ذخیره شده و دوباره مورد استفاده قرار بگیرد. بهتر است همیشه از انجام کارهای غیر ضروری جلوگیری شود. در مثال زیر، ما یک بلوک کد داریم که اغلب اجرا میشود (در این مورد، آن شامل یک حلقه صریح است؛ اما برای مثال میتوان آن را با یک عبارت پیوند و مورد ارزیابی قرار داد). در این مثال مشکل را با در نظر گرفتن شناسه "rect" و خاصیت رنگ "color" آن را چندین بار تغییر و تولید میکنیم. این مثال کاری که میخواهیم را انجام میدهد، اما روش بهینه شده ای نیست بنابراین مثال زیر بسیار بد خواهد بود: import QtQuick 2.3 Item { width: 400 height: 200 Rectangle { id: rect anchors.fill: parent color: "blue" } function printValue(which, value) { console.log(which + " = " + value); } Component.onCompleted: { var t0 = new Date(); for (var i = 0; i < 1000; ++i) { printValue("red", rect.color.r); printValue("green", rect.color.g); printValue("blue", rect.color.b); printValue("alpha", rect.color.a); } var t1 = new Date(); console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations"); } } برای اینکه کد فوق بهینه سازی شود بهتر است به صورت زیر باشد: import QtQuick 2.3 Item { width: 400 height: 200 Rectangle { id: rect anchors.fill: parent color: "blue" } function printValue(which, value) { console.log(which + " = " + value); } Component.onCompleted: { var t0 = new Date(); for (var i = 0; i < 1000; ++i) { var rectColor = rect.color; // resolve the common base. printValue("red", rectColor.r); printValue("green", rectColor.g); printValue("blue", rectColor.b); printValue("alpha", rectColor.a); } var t1 = new Date(); console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations"); } } فقط این تغییر ساده باعث بهبود عملکرد قابل توجهی میشود. بنابراین، توجه داشته باشید که کد بالا را میتوان حتی بهبود بیشتری داد (از آنجا که ویژگی مورد نظر هرگز در طول پردازش حلقه تغییر نکرده است)، با بالا بردن دقت خارج از حلقه، به صورت زیر است: import QtQuick 2.3 Item { width: 400 height: 200 Rectangle { id: rect anchors.fill: parent color: "blue" } function printValue(which, value) { console.log(which + " = " + value); } Component.onCompleted: { var t0 = new Date(); var rectColor = rect.color; // resolve the common base outside the tight loop. for (var i = 0; i < 1000; ++i) { printValue("red", rectColor.r); printValue("green", rectColor.g); printValue("blue", rectColor.b); printValue("alpha", rectColor.a); } var t1 = new Date(); console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations"); } } پیوند خاصیتها (Property Binding) در صورتی که خواص مرجع هر یک از اتصالات تغییر یابند، به آن خاصیت متصل دوباره ارزیابی خواهد شد. به همین ترتیب، عبارات خواص باید به همان اندازه ساده باشند. اگر شما یک حلقه دارید که در آن پردازشی را انجام میدهید، اما تنها نتیجه نهایی پردازش مهم است، اغلب بهتر است که موقتاً آن را بهروز کرده و در صورت نیاز آن را برای بهروز رسانی یک خاصیت مورد نیاز اختصاص دهید. این کار به منظور جلوگیری از ارزیابیهای مجدد بسیار مفید خواهد بود. مثال ذکر شده زیر این نکته را نشان میدهد که بسیار بد پیاده سازی شده است: import QtQuick 2.3 Item { id: root width: 200 height: 200 property int accumulatedValue: 0 Text { anchors.fill: parent text: root.accumulatedValue.toString() onTextChanged: console.log("text binding re-evaluated") } Component.onCompleted: { var someData = [ 1, 2, 3, 4, 5, 20 ]; for (var i = 0; i < someData.length; ++i) { accumulatedValue = accumulatedValue + someData[i]; } } } حلقه ای که در رویداد onCompleted میباشد، موجب میشود تا خاصیت متن text به تعداد ۶ بار مجدداً مورد ارزیابی قرار بگیرد (که در نتیجه هر گونه پیوند مرتبط با مقدار متن متکی است) همچنین کنترلر سیگنال onTextChanged هر یک را مجدداً ارزیابی میکند و این موجب میشود متن هر بار نمایش داده شود. این امر ضروری نیست چرا که هدف ما دسترسی به ارزش نهایی آن خواهد بود. روش پیشنهادی به صورت زیر خواهد بود: import QtQuick 2.3 Item { id: root width: 200 height: 200 property int accumulatedValue: 0 Text { anchors.fill: parent text: root.accumulatedValue.toString() onTextChanged: console.log("text binding re-evaluated") } Component.onCompleted: { var someData = [ 1, 2, 3, 4, 5, 20 ]; var temp = accumulatedValue; for (var i = 0; i < someData.length; ++i) { temp = temp + someData[i]; } accumulatedValue = temp; } } بارگذاریها و منابع مرتبط به تصاویر تصاویر بخش مهمی از رابط کاربری هستند. متأسفانه، به دلیل زمان بارگیری آنها، میزان حافظه ای که مصرف میکنند نیز قابل توجه است. بنابراین توجه داشته باشید که در صورتی که اپلیکیشن شما شامل تصاویری با اندازه بزرگتر هستند، اما شما آن را در اندازهی کوچکتر از واقعی خود نشان میدهید. در این صورت بهتر است اندازه سورس آن را نیز مشخص کنید که در خاصیت "sourceSize" مشخص میشود. این کار باعث میشود تا مطمئن شویم عنصور تولید شده با مقیاس کوچکتری در حافظه نگهداری میشود. البته مراقب این نیز باشید که تغییر اندازه سورس موجب میشود تصویر دوباره بارگیری شود. بارگیری غیرهمزمان (Asynchronous) معمولاً برنامههای زیبا و با کیفیت دارای تصاویر با کیفیت نیز هستند، بنابراین لازم است تا اطمینان حاصل شود که بارگیری یک تصویر یک رشته از UI را بلوک یا مسدود نمیکند. خاصیت asynchronous در نوع QML Image را با مقدار true تنظیم کنید تا بارگیری غیرهمزمان از تصاویر بر روی سیستم فایلهای محلی بارگیری شود. این کار از وارد کردن فشار بر روی تصاویر و رابط کاربری جلوگیری خواهد کرد که نتیجهی آن حفظ زیبایی رابط کاربری شما در زمان بارگذاری تصاویر خواهد شد. نکات ریز اما مهم از سایه پردازیها و تصاویری که در حین زمان اجرا در ترکیب تصاویر شما ایجاد میشوند دوری کنید. توجه داشته باشید که در صورت عدم نیاز از خاصیت smooth استفاده نکنید. فعال سازی این خاصیت موجب تولید تصاویر صاف و با کیفیت میشود که در سخت افزاهای قدرتمند توصیه میشود. در سخت افزارهای ضعیف تولید تصاویر صاف زمانبر خواهد بود و در صورتی که اندازهی تصویر واقعی نباشد بر روی نتیجهی آن تاثیری نخواهد داشت. از نقاشی و یا رسم طرح بر روی یک ناحیه به صورت پشت سر هم اجتناب کنید. از نوع Item به عنوان عنصر ریشه به جای Rectangle استفاده کنید. عناصر موقعیت با لنگر استفاده از لنگرها (anchors) به جای اتصالات (bindings) به یک آیتم موقعیت نسبتاً تاثیر بیشتری خواهد داشت. برای مثال برای اتصال موقعیت rect2 به rect1 را توجه کنید: import QtQuick 2.3 .... Rectangle { id: rect1 x: 20 width: 200; height: 200 } Rectangle { id: rect2 x: rect1.x y: rect1.y + rect1.height width: rect1.width - 20 height: 200 } .... این کار را میتوان توسط لنگرها به طور بسیار موثری انجام داد: import QtQuick 2.3 .... Rectangle { id: rect1 x: 20 width: 200; height: 200 } Rectangle { id: rect2 height: 200 anchors.left: rect1.left anchors.top: rect1.bottom anchors.right: rect1.right anchors.rightMargin: 20 } .... تنظیم موقعیت توسط اتصالات (با اختصاص دادن عبارتهای اتصال به محورهای x و y طول و ارتفاع به عنوان خواص یک شیء به جای استفاده از لنگرها) هرچند به حداکثر انعطاف پذیری اجازه میدهد اما نتیجه تولیدی آن نسبتاً کُند است. در نظر داشته باشید که اگر شیء شما به صورت داینامیک (پویا) تغییر پیدا نمیکند، روش مناسب تغییر موقعیت استفاده از خاصیتهای y، x، width و height میباشد که متناسب و وابسته به والد خود میباشد. در صورتی که میخواهید وابستگی ایجاد نشود بهتر است از لنگرها استفاده کنید. در مثال زیر، اشیاء مستطیل (Rectangle) فرزند در یک مکان مشابهی قرار گرفته اند، اما کدهای مرتبط به لنگرها (anchors) نشان میدهد که موقعیت آن شیء به صورت ثابت مقدار دهی شده است. import QtQuick 2.3 Rectangle { width: 60 height: 60 Rectangle { id: fixedPositioning x: 20 y: 20 width: 20 height: 20 } Rectangle { id: anchorPositioning anchors.fill: parent anchors.margins: 20 } } مدلها و نمایشها اکثر برنامه های کاربردی (Application) حداقل از یک مدل (Model) تغذیه داده را به نمایه (View) ارسال میکنند. بعضی از مواردی که توسعه دهندگان برای به حداکثر رساندن عملکرد به آنها باید توجه داشته باشند وجود دارد. مُدلهای سفارشی سمت سیپلاسپلاس این بسیار خوب است که شما مدلهای دادهای سفارشی خود را سمت ++C برای استفاده ار نمایهی QML بنویسید. اما باید توجه داشته باشید این کار به شدت بستگی به کاربرد آن در موقعیت خودش را دارد که برخی از دستورالعمل های کلی به شرح زیر هستند: تا جایی که ممکن است ناهمزمان باشد. تا جای ممکن بصورت ناهمزمان، تمام پروسههای پردازشی را در یک نخ با (اولیت پایین) انجام دهید. عملیات بکاند را به صورت دسته ای انجام دهید تا (به طور بالقوه آهسته) عملهای I/O و IPC به حداقل برسد. از یک پنجره مجزا برای نتایج کَش که پارامترهایش به پروفایلینگ کمک میکنند، استفاده کنید. این مهم است که توجه داشته باشیم استفاده از یک نَخ (Thread) کارآمد با کمترین اولویت توصیه میشود تا خطر قحطی (starving) را در نخ های رابط کاربری به حداقل برساند. همچنین به یاد داشته باشید که مکانیزم هماهنگ سازی و قفل کردن میتواند عامل مهمی برای عملکرد آهسته باشد، بنابراین لازم است از اعمالِ قفل غیر ضروری جلوگیری (صرف نظر) شود. نوع لیست مُدل (ListModel) در QML کیوامال (QML) یک نوع ListModel ای را فراهم میکند که میتواند برای ارسال داده به یک نوع از ListView استفاده شود. این باید برای اکثر موارد مناسب باشد و تا زمانی که به درستی استفاده شود نسبتاً عملکرد درستی داشته باشد. تجمع در داخل یک نخ عناصر ListModel را می توان در یک نخِ کاری (با اولویت پایین) در JavaScript جابجا کرد. توسعهدهنده باید صریحاً متد sync() را که به عنوان یکی از خواص موجود در ListModel میباشد را داخل یک WorkerScript صدا بزند تا تغییرات همزمان با نَخ اصلی صورت بکیرد. جهت کسب اطلاعات بیشتر مستندات WorkerScript را مطالعه کنید. لطفاً توجه داشته باشید که با استفاده از یک عنصر WorkerScript یک موتور جاوا اسکریپت جداگاه ایجاد میشود (چرا که موتور جاوا اسکریپت در هر نَخ (Thread) میباشد). این باعث افزایش مصرف حافظه خواهد شد. چرا که عناصر متعدد (چندگانه) WorkerScript همه از یک نَخ استفاده خواهند کرد. بنابراین تاثیر شدیدی در حافظهی استفاده شده توسط وُرکر دوم و سوم وارد خواهد کرد که در زمان اجرای برنامه و وُرکر اسکریپت اول تاثیر آن بسیار ناچیز خواهد بود. از نقشهای (Roles) پویا استفاده نکنید عنصر ListModel در QtQuick 2 بسیار کارآمدتر از QtQuick است. بهبود عملکرد عمدتاً از پیش فرضهای مربوط به نوع نقشها (Roles) در هر عنصر در یک مدل داده میشود. اگر نوع آن تغییر نکند، عملکرد ذخیره سازی به طور چشمگیری بهبود مییابد. اگر نوع قابلیت تغییر به صورت پویا از عنصر به عنصر دیگری را داشته باشد، بهینه سازی غیر ممکن شده و عملکرد (پرفرمنس - کارآیی) مدل به اندازهی بزرگی بدتر و کُندتر خواهد شد. بنابراین به صورت پیشفرض حالت داینامیک غیر فعال بوده و توسعهدهنده خود باید خاصیت dynamicRoles را به عنوان یکی از خاصیتهای ListModel فعال کند. البته به شدت پیشنهاد میشود برنامهی خود را از اول طراحی کنید اما این قابلیت را فعال نکنید. نمایهها (Views) توجه داشته باشید که نماینده (دلیگیتس یا delegates) باید به طور ساده حفظ شود. به اندازهی کافی از انواع QML در این خاصیتهای ضروری استفاده کنید. هرگونه قابلیت اضافه که بلافاصله مورد استفاده قرار نمیگیرد نیاز نیست. برای مثال اگر نیاز است اطلاعات بیشتری در موقع کلیک بر روی آیتم نمایش داده شود، نیاز نیست که همان لحظه ایجاد و بر روی آیتم نمایان شوند. نباید تا قبل از زمان نیاز ایجاد شوند. لیست زیر، خلاصهی خوبی از مواردی است که باید هنگام طراحی بر روی خاصیت delegate در نظر داشته باشید: عناصری که کمتر در خاصیت delegate هستند، سریعتر می توانند ایجا شوند، و بنابراین سریعتر میتوانند در نمایه (view) مشاهده و اسکرول شوند. تعداد پیوندها (اتصالات) را در delegate به حداقل تعدادشان نگه داری کنید. از لنگرها (anchors) به جای اتصال برای موقعیتهای نسبی در یک delegate استفاده شود. از به کار گیری عناصر ShaderEffect در delegate اجتناب شود. هرگز خاصیت clip را در خاصیت delegate فعال نکنید. نکته: شما میتوانید ویژگی cacheBuffer یک نمایه (view) را تنظیم کنید تا اجازه ایجاد و ارسال غیر مستقیم به delegate خارج از ناحیه قابل مشاهده را ایجاد کنید. استفاده از cacheBuffer برای delegate های نمایشی توصیه می شود. توجه داشته باشید که خاصیت delegate یک cacheBuffer اضافی را در حافظه نگه میدارد، بنابراین مقدار حاصل از استفاده cacheBuffer باید با استفاده از حافظه اضافی متعادل شود. توسعهدهندگان خود باید از معیارهای سنجش (بنچ مارکها) برای یافتن بهترین مقدار مناسب برای استفاده را انجام دهند. چرا که افزایش حافظه ناشی از استفاده cacheBuffer میتواند در بعضی از موارد نادر، باعث کاهش نرخ فریم در هنگام پیمایش (اسکلرول) شود. جلوههای بصری فناوری کیوت کوئیک ۲ شامل چند ویژگی است که به توسعهدهندگان و طراحان اجازه میدهد تا رابط کاربری فوق العاده جذاب ایجاد کنند؛ تغییرات پویا (داینامیکی) و همچنین جلوههای بصری میتوانند برای یک اثر بزرگ در برنامهی کاربردی مورد استفاده قرار گیرد. اما هنگام استفاده از بعضی از ویژگیهای QML، باید نکاتی را در نظر گرفت که میتوانند دلالت بر کارآیی (پرفرمنس) را داشته باشند. انیمیشنها به طور کلی، متحرک سازی (انیمیشن سازیِ) یک خاصیت (پراپرتی) میتواند سبب شود تا اتصالاتی که به یک خاصیت دیگر اشاره میکند را مجدداً مورد ارزیابی قرار گیرد. معمولاً این مورد مطلوب است، اما در برخی از موارد ممکن است بهتر باشد قبل از انجام متحرک سازی (انیمیشن سازی) اتصالات را غیر فعال کنید، و سپس آن انیمیشن را تکمیل کنید. از اجرای کدهای جاوا اسکریپت در طول یک انیمیشن اجتناب کنید. برای مثال، اجرای یک عبارت پیچیده جاوا اسکریپت برای هر فریم از انیمیشنِ یک خاصیت مانند x باید اجتناب شود. توسعهدهندگان باید در استفاده از انیمیشنهای اسکریپتی دقت کنند، زیرا آنها در یک نخ اصلی اجرا میشوند (در نتیجه در صورتی که اجرا و تکمیل انیمیشن بیش از حد طول بکشد)، ممکن است فریمهایی را پرش کرده و موجب کاهش کارآیی اصلی آن شود. ذَرات، پارتیکل (Particles) ماژول Qt Quick Particles اجازه میدهد تا ذراتی را برای زیبایی هرچه بهتر رابط کاربری اضافه شود. با این حال، هر پلتفرم دارای قابلیتهای سخت افزاری مختلفی است و ماژول Particles قادر به محدود کردن پارامترهای سخت افزاری شما نمیباشد. بنابراین زمانی که شما ذرات بیشتری برای تولید (رندر) میخواهید (هرچه بزرگتر می شوند)، سرعت بیشتری برای پردازش سخت افزار گرافیکی شما نیاز خواهد بود تا بتواند سرعت تولید آنها را با نرخ ۶۰ فریم بر ثانیه اجرا کند. بنابراین ذرات بیشتر خواهان پردازندههای مرکزی سریعتری میباشند. بنابراین، این بسیار مهم است که تمام ذرات و اثرات آنها را بر روی پلتفرمهای هدف خود با دقت آزمایش کنید، تا برای کالیبره کردن تعداد و اندازه ذرات قابل تولید با نرخ ۶۰ فریم به نتیجه قابل قبول برسید. لازم به ذکر است که برای جلوگیری از شبیه سازی غیر ضروری یک سیستم ذره را میتوان غیر فعال کرد (به عنوان مثال عنصری را غر قابل مشاهده کنید) این کار باعث میشود تا شبیه سازیهای غیر ضروری غیر فعال شوند. عملکرد سیستم ذرات با مقایس تعداد ذرات نگه داری میشود. پس از نمونه برداری از اثر مورد نظر، با کاهش مقدار ذرات، عملکرد آن را میتوان بهبود داد. برعکس، اگر عملکرد آن به خوبی و در حد قابل قبول باشد، میتوان تعداد ذرات را تا زمانی که در آن نقطه قرار میگیرد افزایش دهید(این کار باعث بهبود خواهد شد). همانند ShaderEffect، عملکرد سیستم ذرات تا حد زیادی وابسته به سخت افزار گرافیکی است که در حال اجرا میباشد. همچنین دقت کنید مقدار دهی loop در مصرف پردازنده بسیار موثر است، برای مثال اگر از SequentialAnimation استفاده میکنید، بهتر است مقدار loop را محدود در نظر بگیرید. در صورتی که مقدار آن برابر با Animation.Infinite باشد درصد قابل توجهی از پردازنده را درگیر خود خواهد کرد. کنترل طول عمر عنصر با تقسیم کردن یک برنامه به اجزای ساده، ماژولار، هرکدام از آنها در یک فایل QML منعکس میشوند، میتوانید زمان راه اندازی برنامه را سریعتر و کنترل بیشتری از استفاده از حافظه را به دست آورده و تعداد عناصر فعال اما غیر قابل مشاهده را در برنامه خود کاهش دهید. به طور کلی سعی کنید برای هر ماژول یا بخشی از برنامه یک سند جداگانه از QML را فراهم کنید. مقداردهی اولیه سریع (از روی تنبلی)! موتور QML برخی چیزها را به صورت هوشمندانه (یا زیرکانه) انجام میدهد تا اطمینان حاصل شود که بارگذاری و مقدار دهی اولیه اجزاء باعث نمیشود تا فریمها از بین بروند. با این حال هیچ راهی برای کاهش زمان راه اندازی بهتر از این وجود ندارد که شما کارهایی را تا زمانی که به آنها نیاز ندارید را انجام ندهید و از آنها اجتناب کنید. این ممکن است با استفاده از اجزای پرکاربردی مانند نوع Loader یا ساخت کامپوننت (جزء)های پویا (Dynamic Object Creation) انجام شود. استفاده از بارکننده (لودر - Loader) لودر یک عنصری است که اجازه میدهد بارگذاری و تخلیه پویا بر روی اجزاء انجام شود. با استفاده از ویژگی "active" در Loader، مقدار دهی اولیه میتواند تا زمان لازم انجام شود. با استفاده از تابع setSource() مقدار دهی اولیه میتواند تامید شود. تنظیم خاصیت asynchronous بر روی مقدار true میتواند تاثیر بر روی بهبود عملکرد بر روی کامپوننت (جزء) در زمان نمونه سازی داشته باشد. استفاده از سازندهی پویا توسعه دهندگان میتوانند از یک تابع Qt.createComponent() برای ایجاد یک مولفه به صورت پویا در زمان اجرا از داخل جاوا اسکریپت استفاده کنند و سپس createObject() را برای نمونه سازی آن، فراخوانی کنند. نابود کردن عناصر استفاده نشده عناصری که مخفی هستند به عنوان فرزندی از عناصر غیر بصری محسوب میشوند. برای مثال زمانی که یک زبانه از TabBar یا TabWidget انتخاب شده است و نمایش داده میشود به لایلی باید سریع مقدار دهی اولیه شوند و زمانی که از آن به مدت طولانی استفاده نمیشود و این خود باعث بارگذاری اضافی است. بنابراین در صورت استفاده از این روش جهت جلوگیری از این هزینه مداوم در زمان اجرا ( که شامل تولید انیمیشن، اتصالات، رندرینگ و غیره...) به صورت خودکار حذف میشوند. نکته: یک آیتم بارگذاری شده با یک نوع عنصر Loader ممکن است توسط تنظیمات مجدد خاصیت source یا sourceComponent آزاد شود. در حالی که موارد دیگر ممکن است به صورت صریح با فراخوانی متد destroy() بر روی آنها منتشر شود. در بعضی از موارد ممکن است لازم باشد آیتم فعال را ترک کرده و یا حداقل آن را نامرئی کنید. این کار موجب میشود سرعت برنامهی شما بهینه شود. تولید (رندرینگ) Rendering گرافیک صحنهای که برای رندر در کیوت کوئیک ۲ استفاده میشود، رابط کاربری بسیار متحرک را به صورت فیزیکی در ۶۰ فریم بر ثانیه ارائه میکند. با این حال برخی چیزها به طور چشمگیری در عملکرد رندرینگ کاهش مییابند. توسعه دهندگان باید مراقب باشند تا از این مشکلات در هر جا که ممکن است اجتناب کنند که به برخی از آنها اشاره شده است. کلیپ کردن (Clipping) کلیپ کردن به صورت پیشفرض غیرفعال است و توصیه میشود تنها زمانی که به آن نیاز دارید فعالش کنید. کلیپ کردن یک اثر بصری دارد، نه بهینه سازی! بنابراین این ویژگی پیچیدگی بیشتری را برای رندرینگ افزایش میدهد. اگر کلیپ فعال باشد، اجزای تولید شده خود و دیگر اجزای فرزندش را به محدوده خود متصل خواهد کرد. این باعث میشود رندرینگ در آن بخش متوقف شده و آن بخش از اشیاء مرتبط و منظم دیده شوند. نکته مهم این است که کلیپ کردن در داخل delegate بسیار نامناسب است و باید از این کار اجتناب شود. چرا که موجب کاهش کارآیی برنامه خواهد شد. نقاشی بیش از اندازه و عناصر نامرئی اگر شما عناصری دارید که توسط عناصر دیگری (مات) یا پوشانیده شده اند، بهتر است از خاصیت visible استفاده کرده و آن را به مقدار false تنظیم کنید. برای مثال در زبانههایی که به صورت پیشفرض یکی از آنها فعال هستند و زبانههای دیگر تا زمان انتخاب مخفی! در این صورت بهتر است آیتمهای آنها به از طرف والد آنها مخفی شوند تا در زمان اجرا بابت نمایش مواردی که مخفی هستند هزینهای نشود. شفاف در مقابل مات محتوای مبهم (مات) عموماً بسیار سریعتر از محتوای شفاف هستند. دلیل این امر این است که محتوای شفاف نیاز به ترکیب (مخلوط) کردن دارند و سیستم رندر کننده به مراتب میتواند نوع مات را بهتر بهینه سازی نماید. یک تصویر با یک پیکسل شفاف به طور کامل به عنوان یک نتیجه کاملاً شفاف تلقی میشود، حتی اگر عمدتاً مات باشد. همین امر برای نوع BorderImage با لبه های شفاف درست است. سایهها نوع ShaderEffect باعث میشود که کد درون خطی GLSL را به صورت یکپارچه در یک برنامه Qt Quick با سربار بسیار کم قرار دهید. با این حال مهم است که بدانید، که قِطعه برنامه نیاز به اجرا برای هر یک از پیکسلها در شکل تولید شده را دارد. هنگام استقرار بر روی یک سخت افزار با توان پایین، شیدرها مقدار زیادی از پیکسلها را پوشش میدهند برای جلوگیری از عملکرد ضعیف، باید یک قطعه شیدر را برای چند دستورالعمل جهت جلوگیری از پرفرمنس ضعیف نگهداری کنید. شیدرهای نوشته شده در GLSL اجازه میدهد تا تبدیلات و جلوههای پیچیدهتری را تولید کنید. با این حال باید با دقت بسیاری از آنها استفاده کرد. استفاده از ShaderEffectSource باعث از پیش رندر شدن صحنه به FBO قبل از کشیده شدن آن میشود . این سربار اضافی میتواند بسیار پرهزینه باشد. تخصیص و جمع آوری حافظه مقدار حافظهای که توسط یک برنامه اختصاص داده میشود و اینکه آن حافظه چگونه اختصاص داده میشود شامل ملاحظات بسیار مهمی هستند. صرف نظر از نگرانیهای مربوط به خارج از حافظه در دستگاههای محدود به حافظه، تخصیص حافظه در پُشته به عنوان یک عمل محاسباتی نسبتاً گران میباشد. در این میان استراتژیهای اختصاصی تخصیص حافظه میتواند باعث افزایش تقسیم دادهها در صفحات شود. خوشبختانه، جاوا اسکریپت از روش مدیریت حافظه خودکار در پُشته (Heap) در قالب GC پشتیبانی میکند که دارای برخی از مزیتها است. اما با این حال دلالت بر مهم بودن برخی موارد دارد. یک برنامه نوشته شده در QML حافظه را از هر دو پُشته از سمت مدیریت حافظه تحت ++C و JavaScript مدیریت میکند. توسعه دهنده نرمافزار باید در رابطه با هر یک از آنها به منظور به حداکثر رساند پرفرمنس آگاه باشد. نکاتی برای توسعهدهندگان برنامه QML نکات و پیشنهادات موجود در این بخش تنها در قالب دستورالعمل هستند و ممکن است در همه شرایط قابل اجرا نباشند. با استفاده از معیارهای تجربی و بررسی بنچ مارکها و همچنین آنالیز و همچنین با استفاده از ومعیارهای تجربی برنامه خودتان بهترین تصمیم ممکن را بگیرید. اگر برنامه شما شامل نمایه (View) های متعدد (به عنوان مثال زبانههای چندگانه) میباشد اما در هر زمان تنها یکی از آنها مورد نیاز است در این صورت برای کم کردن حافظه مصرفی میتوانید از روش مقداردهی سریع (از روی تنبلی) استفاده کنید ? که در بالا به آن اشاره شده است. نابود سازی اشیاء ای که مورد استفاده قرار نمیگیرند اگر شما از روش ساده بارگیری کامپوننتها و یا ساخت اشیاء به صورت پویا در طول یک عبارت جاوا اسکریپتی استفاده میکنید، بهتر است آنها را به صورت دستی توسط متد destroy() نابود کنید. این بهتر از آن است که منتظر باشید تا به صورت خودکار سیستم GC آنها را جمع آوری و نابود کند. در زمانی که نیاز نیست به صورت دستی عمل GC (بازیافت حافظه) را انجام ندهید در اکثر موارد، دستیابی به مجموعه زبالهها به منظور دستیبای به آن نیست. زیرا این کار به مدت زیادی نخهای سمت رابط کاربری را مسدود میکند. این کار باعث میشود فریمها و پرشهایی در انیمیشنهای متحرک به وجود آید که باید از اینگونه هزینه ها اجتناب شود. به طور کلی باید توجه داشته باشید که به صورت مستقیم و دستی همه جا نباید اقدام به نابود سازی حافظه اخصاص یافته شده کنید. اجتناب از اتصال پیچیده گذشته از اینکه اتصالات پیچیده موجب کاهش پرفرمنس (کارایی) میشود استفاده از آنها (برای مثال، زمانی که نیاز است ارزیابی جداگانه تحت کدهای جاوا اسکریپت شود) به صورت پیچیدهای حافظه بیشتری را در هر دو پُشته ++C و JavaScript برای بهینه سازی محاسبات اختصاص میدهند. بنابراین نیاز نیست همیشه از اتصالات پیچیده و ارزیابی آنها تحت JS استفاده کرد. اجتناب از تعریف چند نوع ضمنی یکسان اگر یک عنصر QML یک خصوصیت سفارشی تعریف شده در QML داشته باشد، آن نوع خاصی و ضمنی خود را میگیرد. این مورد در بخش بعدی بیشتر توضیح داده شده است. اگر چندین نوع ضمنی یکسان در یک جزء درون خطی تعریف شده باشند، موجب هدررفتن بخشی از حافظه خواهند شد. در این وضعیت معمولاً بهتر است که جزء را بهصورت صریح تعریف کنیم که بعدا میتواند دوباره استفاده شود. تعریف یک اخاصیت سفارشی اغلب می تواند در بهینه سازی عملکرد سودمندی داشته باشد (برای مثال، برای کاهش تعداد پیوندهایی که مورد نیاز است یا دوباره ارزیابی میشوند)، یا میتواند ماژولار بودن و قابلیت نگهداری یک جزء را بهبود بخشد. در این موارد، استفاده از خواص سفارشی پیشنهاد میشود. با این حال، نوع جدید باید، اگر از بیش از یک بار استفاده می شود، به جزء خود (فایل .qml) به منظور حفظ حافظه، تقسیم شود. استفاده مجدد از اجزای موجود اگر شما در حال تعریف یک جزء جدید هستید، لازم است دوباره بررسی کنید که چنین جزئی در پلتفرم شما وجود دارد یا خیر. در غیر این صورت شما باید موتور QML را مجبور به ساخت و ذخیره سازی نوع داده برای یک نوع که نیاز است کنید که به عنوان یک نوع تکراری که از اجزای موجود می باشد بارگذاری میشود. به جای کتابخانههای اسکریپتی پراگما از انواع تک تک (singleton) استفاده کنید. اگر از یک اسکریپت کتابخانه pragma برلی ذخیره داده های نمونه استفاده میکنید، به جای استفاده از یک نوع تک تکی از QObject استفاده کنید. نتیجه آن در کارآیی بهتر تاثیر گذار خواهد بود و باعث میشود حافظه کوچکتری در پُشتهی جاوا اسکریپت مورد استفاده قرار گیرد. اختصاص دادن حافظه در یک برنامه QML استفاده از حافظه یک برنامه مبتنی بر QML ممکن است به دو بخش تقسیم شود: استفاده از پُشته سمت ++C و پشتهی سمت JavaScript میباشد. برخی از حافظه اختصاص داده شده در هر یک از اجزاء غیرقابل اجتناب خواهند بود. به عنوان آن که توسط موتور QML یا موتور جاوا اسکریپت اختصاص داده میشود. در حالی که بقیه آن وابسته به تصمیمات گرفته شده توسط توسعه دهنده اپلیکیشن میباشد. پشته در ++C شامل موارد زیر خواهد بود: سربار ثابت و اجتناب ناپذیر از موتور QML (پیاده سازی ساختارهای داده، اطلاعات زمینه و غیره). اطلاعات هر جزء کامپایل شده و نوع دادهها، شامل هر یک از انواع و فرا داده هایی میباشد، که توسط موتور QML بسته به نوع ماژولها و کامپوننتهایی است که توسط اپلیکیشن بارگیری میشوند. هر شیءای که در دادههای سی++ (شامل مقادیرِ خاصیت) به همراه هر یک از عناصر متا آبجکت هستند که وابسته به کامپوننت (اجزای) معرفی شده توسط اپلیکیشن میباشند. هر داده ای که به طور خاص توسط QML اختصاص داده میشود که شامل کتابخانههای وارد شده نیز هستند. پشته در JavaScript شامل موارد زیر خواهد بود: سربار ثابت و اجتناب ناپذیر از موتور QML (خودش انواع از قبل ساخته شدهی جاوا اسکریپتی را دارد). سر بار ثابت شده و اجتناب ناپذیر از ادغام جاوا اسکریپت (توابع سازنده برای انواع داده های بارگذاری شده، قالبهای توابع، و غیره). اطلاعات مربوط به هر نوع و و دیگر انواع داخلی توسط موتور جاوا اسکریپت که در زمان اجرا تولید میشود. هر شیء ای که به عنوان داده جاوا اسکریپتی (خاصیتهای نوع var ، توابع جاوا اسکریپتی و هندلرهای سیگنال و عبارات بهینه نشده). متغیرهای اختصاص داده شده در زمان ارزیابی عبارت علاوه بر این، یک پشته جاوا اسکریپتی اختصاص یافته شده برای استفاده از نَخ اصلی و دیگری در پُشته جاوا اسکریپت برای استفاده در WorkerScript اختصاص یافته میشود. اگر یک اپلیکیشن از یک عنصر WorkerScript استفاده نکند متحمل به سربار گیری نخواهد شد. اندازه پشته در جاوا اسکریپت میتواند به چندین مگابایت برسد و بنابراین برنامههای نوشته شده برای دستگاه هایی که دارای محدودی حافظه هستند، ممکن است بهترین با اجتناب از عنصر WorkerScript باشد، با وجود سودمندی آن در مدلها لیستی، که به صورت یکپارچه ذخیره میشوند باشد. توجه داشته باشید که هر دو موتور QML و JavaScript به طور خوکار مخازن خود را از نوع داده های ملاحظه شده تولید خواهند کرد. هر کامپوننت (جزء) توسط یک برنامه بارگذاری میشود که یک نوع متمایز (صریح) بوده و هر عنصر (به جای کامپوننت) ویژگیهای سفارشی خود را در QML که به صورت ضمنی است تعریف میکند. مثال زیر را در نظر بگیرید: import QtQuick 2.3 Item { id: root Rectangle { id: r0 color: "red" } Rectangle { id: r1 color: "blue" width: 50 } Rectangle { id: r2 property int customProperty: 5 } Rectangle { id: r3 property string customProperty: "hello" } Rectangle { id: r4 property string customProperty: "hello" } } نمونههای قبلی مستطیلهای r0 و r1 دارای ویژگیهای اختصاصی (سفارشی) نبودند. بنابراین موتورهای جاوا اسکریپت و QML هر دو آنها را از همان نوع در نظر میگیرند. به عبارت دیگر هر دوی آنها به عنوان یک نوع صریح از Rectangle (مستطیل) در نظر گرفته میشوند. مستطیلهای r2، r3 و r4 هر یک از آنها با داشتن ویژگیهای اختصاصی خود هر کدام با انواع مختلف ضِمنی در نظر گرفته شدهاند. حتی اگر اطلاعات مربوط به ویژگیهای یکسانی داشته باشند. ملاحظات اختصاصی در عُمق حافظه هرگاه تصمیماتی در خصوص تخصیص دادن حافظه یا کارآیی آن به وجود آید، این مهم است که تاثیرات شدید در عملکرد پردازنده مرکزی و مخازن مربوط به آن، صفحه بندیهای سیستمعامل و بازیافت حافظه (GC) در جاوا اسکریپت را در نظر داشته باشید. بنابراین راه حلهای بالقوه باید با دقت بررسی شوند تا مطمئن شوید که بهترین مورد را انتخاب کردهاید. هیچ مجموعهای از دستور العملهای کلی نمیتواند یک درک جامع ای از اصول اساسی علوم رایانه را با یک دانش علمی از جزئیات پیاده سازی کرده و پلتفرمی که یک توسعهدهندهی نرمافزار در حال توسعه آن است را جایگزین کند. تقسیم بندی تقسیم بندی به عنوان یک مسأله برای توسعه در سیپلاسپلاس است. اگر توسعهدهنده برنامه هیچ نوع یا پلاگینی از سیپلاسپلاس را تعریف نکند، ممکن است آنها را در این بخش با خیال راحت نادیده بگیرند. با گذشت زمان، یک برنامه بخش بزرگی از حافظه را برای خود اختصاص داده و دادهها را به آن حافظه ارسال میکند و بعضی اوقات برخی از قسمت های آن را پس از اتمام استفاده آنها را آزاد میکند. این میتواند منجر به «حافظه آزاد» شده ای در تکههای غیر مجاور شود که نمیتواند برای برنامه های کاربردی دیگر توسط سیستمعامل مورد استفاده قرار گیرد. همچنین تاثیر شدیدی بر روی ذخیره سازی پنهان و دسترسی به ویژگیهای یک اپلیکیشن میگذارد. زیرا دادههایی که زنده هستند (در حال استفاده) هستند، ممکن است در بسیاری از صفحات مختلف حافظه فیزیکی گسترش یابند. این به نوبه خود میتواند سیستمعامل را مجبور به (swap) یا مبادله کند که میتواند سبب شود تا عمل I/O ایجاد شود که به شدت عمل آهستهای بشمار میآید. تقسیم بندی میتواند توسط دیگر موارد تخصیص دهنده حافظه، با کاهش میزان حافظهای که در هر زمان با دقتِ مدیریتِ زمان زندگیِ اشیاء مورد بررسی قرار گیرد. با تمیز کردن و باز سازی دورهای از حافظهها یا با استفاده از زمان اجرا بر روی حافظه از تجزیه آن میتوان جلوگیری کرد که توسط سیستمعامل بازیافت حافظه خودکار (GC) مانند جاوا اسکریپت ممکن است. بازیافت حافظه جاوا اسکریپت سیستم بازیافت حافظه به صورت خودکار را فراهم میکند. حافظه ای که در دسته جاوا اسکریپتی قرار دارد (بر خلاف پُشته در سیپلاسپلاس) متعلق به موتور خود جاوا اسکریپت است. این موتور به طور دورهای تمامی دادههای نا مشخص (غیر قابل استفاده) را در پُشتهی جاوا اسکریپت جمع آوری میکند. پیامدهای بازیافت حافظه بازیافت حافظه، مزایا و معایبی دارد. این به این معنی است که مدیریت عمر مفید شیء به صورت دستی اهمیت کمتری دارد. با این حال، این بدان معنی است که یک عمل بالقوه طولانی مدت ممکن است توسط موتور جاوا اسکریپت در زمانیکه که خارج از کنترل توسعهدهنده نرم افزار است آغاز شود. استفاده از پُشته در جاوا اسکریپت با دقت بسیاری توسط توسعهدهنده برنامه مورد توجه قرار می گیرد. لذا تکرار و مدت زمان بازیابی حافظه ممکن است تاثیر منفی بر تجربه نرمافزار داشته باشد. فراخوانی بازیابی حافظه یک برنامه نوشته شده در QML (به احتمال زیاد) در یک مرحلهای به بازیافت حافظه (GC) نیاز دارد. در صورتی که حجم حافظه آزاد شده کم باشد سیستم بازیافت خودکار حافظه توسط موتور جاوا اسکریپت انجام میشود. بعضی اوقات این کار در صورتی که توسعهدهندهی نرمافزار تصمیمی در مورد اینکه چه زمانی بازیافت حافظه را انجام دهند نگرفته باشد میتواند مناسب باشد. (اگر چه که معمولاً این مورد مطرح نمیشود). توسعهدهنده نرمافزار احتمالاً میداند که برنامه چه زمانی را به مدت قابل ملاحظهای بیکار است. اگر یک برنامه QML از حافظه بسیار زیادی از پُشته جاوا اسکریپت را مصرف کند، باعث میشود چرخه و تکرارهای مکرری در بازیافت حافظه صورت گیرد که در وظایف حساس بر روی کارآیی تاثیر خواهد گذاشت. مانند (لیست پیمایش، انیمیشنها، و غیره). توسعهدهنده نرمافزار ممکن است بهطور دستی به بازیافت حافظه در طول دوره صفر فعالیت کمک کند. دوره های بیکاری برای انجام بازیافت حافظه ایده آل هستند چراکه کاربر هیچگونه تضعیفی را در تجربه کاربری خود (فریمهای پرش شده، انیمیشنهای پرتحرک و نامنظم و غیره) حس نخواهدکرد؛ که این تضعیف تجربه، درنتیجه فراخوانی بازیافت حافظه به هنگام فعالیت برنامه رخ میهد. توسعهدهنده نرمافزار احتمالاً میداند که برنامه چه زمانی را به مدت قابل ملاحظهای برای بیکاری بکار میگیرد. اگر یک برنامه QML از حافظه بسیار زیادی از پُشته جاوا اسکریپت را مصرف کند، باعث میشود چرخه و تکرارهای مکرری در بازیافت حافظه صورت گیرد که در وظایف حساس بر روی کارآیی تاثیر خواهد گذاشت. مانند (لیست پیمایش، انیمیشنها، و غیره). از طرفی ممکن است توسعهدهنده با دستکاری بازیافت حافظه موجب تخریب آن شوند. بازیافت حافظه ممکن است به صورت دستی با فراخوانی gc() در جاوا اسکریپت اعمال شود. این باعث میشود یک چرخه بازیافت جامع از حافظه صورت بگیرد که ممکن است مدت زمانی بین چند صد تا بیش از هزار میلی ثانیه برای تکمیل آن سپری شود. بنابراین در صورت امکان باید از آن اجتناب شود. حافظه در مقابل کارآیی در بعضی موارد ممکن است که زمان پردازش حافظه برای سبک سنگین کردن افزایش مصرف حافظه کاهش یابد. برای مثال، ذخیره سازی نتیجه یک جستجوی نماد که در یک حلقه تنگ به یک متغیر موقت در یک عبارت جاوا اسکریپتی استفاده میشود که در بهبود ارزیابی این عبارت تاثیر قابل توجهی خواهد داشت. اما این شامل تخصیص یک متغیر موقت میباشد. در بعضی از موارد، این سبک سنگین کردن ممکن است معقول باشد (مانند موارد فوق، ک تقریباً همیشه منطقی هستند)، اما در موارد دیگر ممکن است بهتر باشد تا اجازه دهیم تا پردازش طول بکشد تا از افزایش فشار بر روی حافظه سیستم جلوگیری شود. در بعضی از موارد، تاثیر افزایش فشار بر روی حافظه میتواند شدید باشد. در برخی موارد، استفاده دوباره از حافظه ممکن است برای به دست آوردن عملکرد پیشنهادی منجر به افزایش ترافیک صفحات یا ترافیک بر روی حافظه نهان شود که باعث کاهش عملکرد شدید آن خواهد شد. این همیشه برای ارزیابی لازم است، تاثیر تعاملات با دقت به منظور تعیین اینکه بهترین راه حل در یک وضعیت خاص است مهم هستند.-
- عملکرد
- استاندارد نویسی
-
(و 5 مورد دیگر)
برچسب زده شده با :