مفهوم (رویکرد، الگو) zero allocation به چه چیزی اشاره می کند؟ بدفهمی این رویکرد در کجا نهفته شده است؟
خیلی پیش میاد برای خود من که جاهای مختلف به این مفهوم اشاره بشه، ولی درک درستی از آن وجود نداشته باشه در اون گفت و گو (
نمونه)، که منجر به ایجاد انواع خطاها شناختی و در نهایت خطاهای تصمیم سازی می کنه.
اولین اشتباهی که رایج هست این هست که یک بد فهمی زیاد حول دو الگوی
zero allocation و
Object pool pattern وجود دارد. به صورت لغوی هم اگر بررسی کنیم zero به معنای دقیقا هیچ می باشد نه حتی یک تخصیص. پس قطعا reuse کردن یک مقدار allocate شده (عموما در بخشی به ساختار داده heap) در استفاده های تکراری با نگهداری آدرس مقدار تخصیص داده شده در یک pool را به عنوان zero allocation نباید در نظر گرفته شود. این رویکرد همانطور که در بالا نام برده شد، به نام Object pool pattern
شناخته می شود و استفاده از آن شرایط خاصی را طلب می کند. لذا اگر به خوبی مفهوم #memory_management تسلط داشته باشیم براحتی می تونیم این اشتباه (یکی دانستن این دو الگو) را متوجه بشیم. قبلا هم بارها تاکید کردیم که بهتره از تفکرات خوبی که در چندین دهه بوجود آمده استفاده کنیم و از گمانه زنی های بی مورد در خصوص اشاره به مفاهیم قدیمی دوری کنیم. مخصوصا مفاهیمی که حول OOP وجود دارد بدلیل غنای فکری نه به صورت نحوه پیاده سازی در زبان های مدعی، بلکه به استناد مستندات اکثرا دانشگاهی، می توانند مرجع و خوراک فکری خوبی برای ما باشند.
حال چرایی ادعای کذب کتابخانه هایی مثل fasthttp در زبان Go را متوجه می شویم. همین اول بگم سوتفاهم پیش نیاد که این کتابخانه یا زبان بد هستند، اصلا اینجوری نیست و ما نمی خوایم حتی 1% این حس را منتقل کنیم. فقط منظور این هست که استفاده از رویکرد pool در یک کتابخانه مثل همین fasthttp باعث ادعای دروغین zero
allocation نباید بشود که گمراهی به همراه بیاورد.
نکته مهم که باید همیشه یادمون باشه که به
object life cycle باید دقت کنیم و بدون در نظر گرفتن رویکرد pool به توسعه بپردازیم. چرایی اهمیت این قضیه، باز نمونه عدم دقتش میشه کتابخانه fasthttp که بدلیل allocate کردن زیاد برای یک object که قرار reuse بشه که باعث نیاز به reinit کردن زیاد خواهد داشت. و می دونیم که وقتی allocate های ما زیاد باشه یعنی درگیری بیشتر رم بجای کش های cpu که قطعا باعث افزایش مصرف cpu با نرخ کارکرد پایین به دلیل نیاز مبرم به اجرای دستورات مقداردهی رم. لذا هر چه ما کمتر از runtime memory management استفاده کنیم بهره وری نرم افزار به شدت بالاتر خواهد بود، نه در حد چند درصد بلکه چند صد درصد.
نمونه های زیادی در زبان هایی با کنترل زیاد روی memory management مثل C یا Rust وجود داره ولی عموما در زبان های مثل Go به جز راهکارهای به شدت unsafe به هیچ عنوان امکان پیاده سازی این مفهوم zero
allocation وجود ندارد.
https://github.com/rikvdh/zabuffer
https://github.com/nrc/zero/blob/master/src/lib.rs
قطعا می دونیم نمیشه توی یک پست چند خطی همه این موضوعات را باز کنیم و قصد ارائه عمق موارد، مثل همیشه نیست و صرفا #تلنگر_ذهنی و ایجاد پرسش هدف پست ها هست. و قطعا قصد ساده انگاری این موضوع را هم نداریم و می دانیم در نرم افزارهای چند نخ (thread) آن هم در user space قطعا مفاهیمی مثل stack و heap و alloc به شدت پر جزییات تر از این حرف ها، در چند خط هست.
در نهایت بیاییم با استفاده دقیق تر از کلمات، جامعه تخصصی حرفه ای تری را شکل بدهیم که نخواهیم سر پایه ای ترین موضوع یعنی توافق روی
معنا و مفهوم کلمات ساعت ها وقت یکدیگر را بگیریم.
هیچ فرصتی را برای مطالعه حتی روی کلماتی که فکر می کنیم خیلی بدیهی هستند را از دست ندهیم. (تلنگر قوی حتی به خودم)