ممنون استاد علی
میخوام مثل فتوشاپ ، وقتی ابزار eraser را انتخاب میکنم و opacity شو (مثلا 50 درصد) تغییر میدم ، alpha اش نصف شه
توی آلفا و ایناها مشکلی نیست . ولی بهترین سودوکدی که وقت پردازنده را نگیره و پردازنده سریع اون کد رو اجرا کنه ، چیه؟
توی ذهنم این الگوریتم هست . فرضا ابعاد eraser ام 32 در 32 هست . opacity اش هم 50 درصد . کاربر هر جا را که کلیک کرد ، در بیت مپ مورد نظر ، در ابعاد eraser (یعنی 32 در 32 که میشه 1024 بار) ، رنگ هر پیکسل رو در eraser بگیره و آلفای اون پیکسل را هم بگیره و آلفاش را به همون اندازه (مثلا برای 50 درصد ، نصف مقدار آلفا ایی که در اون پیکسل هست) ست کنه . و رنگ همون پیکسل را دوباره در همون پیکسل ست کنه . هر وقت هم موس را حرکت میدیم و در حال کلیک چپ هستیم ، همین الگوریتم اجرا شه برای همه ی نقاط
منتها این الگوریتم خیلی کنده . وقتی موس درگ بشه ، پارازیت میندازه
سودوکد بهتر هست؟
الگوریتم تون ایراد نداره، روش اجرا تون ایراد داره. من کدتون رو ندیدم ولی میتونم با یک مثال ساده نامربوط بگم اشکال کجاست، فرض کنید که قراره اسم ده تا مشتری که بیشترین خرید رو در این ماه داشتن بگید. الگوریتم بهینه این میشه که لیست خرید های این ماه رو استخراج کنید، بر اساس مشتری گروه بندی کنید، بر اساس مجموع مبلغ هر گروه نزولی مرتب سازی کنید و اسم ده تا مشتری بالای لیست رو اعلام کنید. اما الگوریتم غیر بهینه چیه؟ یک حلقه با i رو برای 10 تکرار ایجاد می کنه، ده بار لیست مشتریان که این ماه خرید داشتند رو جدا کنید (9 بار بیشتر از الگوریتم بهینه)، هر بار لیست رو گروه بندی کنید (که 9 بارش اضافیه). هر بار اون لیست رو نزولی مرتب سازی کنید (9 بارش اضافیه)، و هر با مشتری شماره i ام بالای لیست رو در لیست خروجی درج کنید. نهایتا وقتی i به 10 رسید به همون نتیجه الگوریتم بهینه میرسید، اما 9 بار استخراج داده و 9 بار گروه بندی و 9 بار مرتب سازی بیخودی و تکراری دارید. برای همین کند میشه. اونم نه یکمی، خیلی کند میشه. اینجا چی باعث بهینه شدن شده؟ اینکه تا جایی که میشده کاری که برای 10 مورد مشترکه یکجا و فقط یکبار انجام شده، نه تک تک برای هر مشتری.
الگوریتمی که شما برای اون 1024 پیکسل می نویسید هیچ بخشی رو مشترکی و فقط یکبار انجام نمیده، شما هر روالی نوشتید برای 1024 مورد تکراری ئه، یک بخشی اش اصلا لازم نبوده و یک بخشی اش بر اساس کاری که برای پیکسل قبلی انجام دادید قابل دسترسی بوده و یک بخشی اش رو میشه بر اساس شباهت روال خلاصه سازی کرد. خیلی موارد سربار رو نمی بینید چون از روالی مثل GetPixel و شیء ای مثل Color استفاده می کنید، پشت اون روال های زیادی است که سطر های زیادی کد داره. وقتی برای هر پیکسل اون کد ها رو اجرا می کنید بخش زیادی اش تکراری و بیمورد میشه. فتوشاپ نمیاد با GetPixel یا چیزی شبیه به اون دونه دونه پیکسل ها رو استخراج کنه. از اون مهمتر، برای روال شما فرقی می کنه که R و G و B چی باشند؟ نه، شما فقط با A کار دارید، اما از متد هایی استفاده می کنید که مجبور هستند R و G و B رو بخوانند، تفکیک کنند و مجددا ترکیب کنند و بنویسند، اونم با متغیر و پروپرتی و یک عالمه چک کردن هایی که مقداری که می دهید در محدوده بایت 0 الی 255 هست یا نیست. این کد ها هستند، شما نمی بینیدشون ولی هستند. برای همینه که اگه مقدار 256 رو بدید خطا میگیره. اون خطا از کجا میاد؟ از اینجا که داره مقدار ورودی چک میشه. در الگوریتم بهینه A / 2 که چک کردن لازم نداره. اما شما خودتون روالی بکار می برید که چک می کنه، موقعیت x,y رو هر بار پیدا می کنه، الگوریتم بهینه میدونه که موقعیت x+1,y نسبت به موقعیت x,y فقط چهار بایت جابجایی داره و نیازی نیست جمع و ضرب هایی برای پیدا کردن موقعیت نقطه بعدی در حافظه انجام بده، اما GetPixel که کاری نداره شما قبلا موقعیت چه نقطه ای رو ازش گرفته بودید. مدام داره محاسبات تکراری انجام میده، سر SetPixel هم همینطور. موقعیتی که با GetPixel خوندید با موقعیتی که با SetPixel می نویسید که فرقی نداره، اما SetPixel که اینو نمیدونه، میاد مجددا موقعیت رو پیدا می کنه. الگوریتم بهینه میدونه که فقط A رو لازم داره که فقط یک بایته، اما الگوریتم غیر بهینه میاد 4 بایت RGBA رو یکجا میخونه که تازه تفکیک شون هم باید بکنه. اینها همه شون سربار دارند، اضافی، تکراری و بدون امکان بهینه سازی. شما متدی مثل GetPixel رو که نمیتونید عوض کنید، بهینه نمیشه. شما باید با حافظه Bitmap مستقیم کار کنید، نه با واسطه تا بتوانید از موارد مشترک فاکتور بگیرید و خلاصه سازی کنید.