اندازه فضای حافظه برای رشته ها در پایتون

رشته ها در پایتون به شیوه یونیکد (Unicode) نگهداری می شوند و پایتون بر پایه کدگذاری (Encodeing) به هر کاراکتر درون رشته تا چهار بایت می تواند فضای حافظه را بدهد که این فضا دهی حافظه می تواند گاهی بسیار هزینه بر باشد. برای کاهش مصرف حافظه و بهبود عملکرد برنامه ، زبان برنامه نویسی پایتون سه شیوه بازنمایی (Representation) درونی برای رشته های یونیکد را به کار می برد.

  • 1 byte per char (Latin-1 encoding)
  • 2 bytes per char (UCS-2 encoding)
  • 4 bytes per char (UCS-4 encoding)
یونیکُد (Unicode) استانداردی برای کُد کردن نویسه‌های (کاراکترهای) رایانه‌ای و نمایش و پردازش متن به اکثر زبان‌های دنیا است. هر زبان یک قالب یونی‌کد دارد.

زمانی که برنامه نویسی می کنیم، از دید پایتون همه رشته ها یکسان هستند و از دید برنامه نویسی رفتاری یکسان را دارند. در پایتون هر چیزی یک شی (Object) است و از این رو همه رشته ها و همه متغیرهای رشته ای، گونه ای (نوعی) از کلاس str هستند.

بنابراین تفاوت میان رشته ها در پایتون در اندازه فضایی از حافظه به بایت است که به رشته داده می شود. برای نمونه برای هر کاراکتر رشته hello (لاتین) یک بایت داده می شود، پس hello باید 5 بایت از حافظه را بگیرد ولی برای هر کاراکتر رشته درود (فارسی - عربی - چینی) دو بایت داده می شود، پس درود باید 8 بایت از حافظه را بگیرد. همچنین کاراکترهای Emoji مانند ? 4 بایت از حافظه را در بر می گیرند.

متد ()getsizeof از ماژول sys

برای آنکه بدانیم یک رشته چه اندازه ای فضای حافظه را اشغال کرده است، می توانیم متد ()getsizeof از ماژول sys را به کار ببریم. در کد زیر سه بار و برای رشته لاتین hello (هر کارکتر یک بایت)، رشته فارسی (هر کاراکتر دو بایت) و کاراکتر Emoji (هر کاراکتر 4 بایت)، متد ()sys.getsizeof را فراخوانی کرده ایم.

https://virgool.io/@linux_internals/%D8%B4%DB%8C%D9%88%D9%87-%D9%87%D8%A7%DB%8C-%DA%AF%D9%88%D9%86%D8%A7%DA%AF%D9%88%D9%86-%D9%81%D8%B1%D9%85%D8%AA-%DA%A9%D8%B1%D8%AF%D9%86-%D8%B1%D8%B4%D8%AA%D9%87-%D9%87%D8%A7-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-dvwf50gbvemy

شکل بالا برگشتی هر بار انجام شدن متد را نشان می دهد ولی می بینید که بر خلاف انتظار ما، یعنی 5 بایت برای hello، اندازه 54 بایت، که برابر است با 49+5 بایت، برگشت داده شده است. یا برای رشته درود، انتظار داریم 8 بایت (چهار تا دو بایت) برگشت داده شود ولی 82 بایت، که برابر است با 74+8 بایت، برگشت داده شده است. در پایان برای تک کاراکتر ? انتظار داریم 4 بایت برگشت داده شود ولی 8 بایت یا 76+4 بایت برگشت داده شده است.

با توجه به آنچه که گفتیم و با توجه به تک فضاهای خالی میان هر واژه، رشته درود بر تو چند بایت را در بر می گیرد. در این جا هر واکه (حرف) 2 بایت و هر فضای خالی نیز 2 بایت را اشغال می کند و در پایان این اندازه از بایت ها باید با 74 جمع شوند. در بر آن رشته hello my froiends هر واکه (حرف) یک بایت و هر فضای خالی نیز یک بایت را اشغال کرده و سپس باید با شماره 49 جمع شوند.

در کد بالا برای آنکه اندازه هر بایت یک رشته دلخواه را بدست آوریم، در متغیرهای any_char_of_str_mem_size یکی از کاراکترهای هم گونه همان رشته را به آن افزوده و سپس اندازه این رشته تازه را از رشته نخستین کم می کنیم. برای نمونه با عملگر + (برای الحاق یا join دو رشته)، کاراکتر a را به انتهای رشته hello افزوده ایم و سپس اندازه آن را از اندازه خود hello کم کرده ایم که می شود 5 - 1 + 5 که برابر است با یک بایت.

تفاوت دو تابع len و ()sys.getsizeof

تابع ()len شمار (تعداد) عناصر درون یک شی را بر گشت می دهد. توجه کنید که یک رشته توالی از کاراکترها است، پس ()len شمار کاراکترها را برگشت می هد. در برابر آن، ()sys.getsizeof اندازه اشغالی از حافظه به بایت را برگشت می دهد.

منبع

دانلود اسکریپت

دیگر آموزش ها