قياس استهلاك الذاكرة بدقة واستخدام pympler في بايثون
مقدمة
يُعَد قياس استخدام الذاكرة في برمجة بايثون موضوعًا مُهِمًّا، وخصوصًا عند التعامل مع هياكل البيانات الكبيرة. لكن العديد من المطورين يواجهون تحديات في الحصول على قياسات دقيقة بسبب اختلاف النتائج بين الأدوات المختلفة. في هذا المقال، سنستكشف كيفية قياس استخدام الذاكرة بدقة ولماذا تعتبر مكتبة Pympler مختلفة تمامًا عن الوظيفة sys.getsizeof.
أساليب قياس استخدام الذاكرة في بايثون
هناك العديد من الطرق لقياس استخدام الذاكرة في بايثون، ومن بينها sys.getsizeof وPympler. تُشتهر وظيفة sys.getsizeof بإرجاع حجم الكائن مباشرة، لكن هذه الطريقة قد لا تُظهر الاستخدام الفعلي للذاكرة إذا كان الكائن يحتوي على مراجع إلى كائنات أخرى. على سبيل المثال، عندما نقوم بإنشاء مجموعة من الأعداد باستخدام NumPy، يمكن أن يُظهر sys.getsizeof حجم الكائن الرئيسي فقط دون احتساب العناصر المكونة له.
لماذا Pympler أكثر دقة؟
مكتبة Pympler، وعلى وجه الخصوص الدالة asizeof، تُقدم منظورًا أعمق لقياس استخدام الذاكرة. تعمل هذه المكتبة على حساب حجم الكائنات ومراجعها، مما يُعطي نظرة أكثر شمولية لاستخدام الذاكرة. من خلال تتبع جميع الكائنات المرتبطة بكائن معين، يمكن لـ Pympler أن تُقدِّر استهلاك الذاكرة بشكل أدق. في المثال السابق، استخدمت كودًا يظهر الاختلافات بين both asizeof وsys.getsizeof:
from pympler import asizeof
from gc import get_referents
import numpy as np
import sys
def getsize(obj):
"""مجموع حجم الكائن والأعضاء."""
seen_ids = set()
size = 0
objects = [obj]
while objects:
need_referents = []
for obj in objects:
if id(obj) not in seen_ids:
seen_ids.add(id(obj))
size += sys.getsizeof(obj)
need_referents.append(obj)
objects = get_referents(*need_referents)
return size
my_set8 = {np.uint8(x) for x in range(256)}
my_set16 = {np.uint16(x) for x in range(65536)}
print(f"{asizeof.asizeof(my_set8)=}")
print(f"{getsize(my_set8)=}")
print(f"{asizeof.asizeof(my_set16)=}")
print(f"{getsize(my_set16)=}")
عند تنفيذ هذا الكود، نحصل على قياسات Memory تختلف بشكل كبير. كما يتضح من النتائج:
asizeof.asizeof(my_set8)=16616
getsize(my_set8)=14808
asizeof.asizeof(my_set16)=4194536
getsize(my_set16)=3801304
فهم الاختلاف في النتائج
يمكن أن تفسر الاختلافات الكبيرة في القياسات بالأسباب التالية:
-
نوع الذاكرة المحسوبة: sys.getsizeof يحسب حجم الكائن نفسه فقط، بينما Pympler تشمل مراجع الكائنات التابعة، مما يؤدي إلى نتائج أكبر.
-
أبعاد الكائنات: في حالة هياكل البيانات المركبة، مثل المجموعات أو القوائم، فإن الأمر يتطلب المزيد من العناية في معالجة الأبعاد المختلفة والمتعددة.
- إدارة الذاكرة: تستخدم Pympler أساليب أكثر تعقيدًا لاكتشاف الذاكرة واستخدامها، بينما sys.getsizeof قد يكون أسهل وأقل دقة.
الخاتمة
عند قياس استخدام الذاكرة، تختلف النتائج بشكل واضح بين مكتبة Pympler والدالة sys.getsizeof. من المهم فهم الآلية التي تعمل بها كل منهما من أجل اتخاذ قرارات مستنيرة حول استخدام الذاكرة في برمجة بايثون. فبدلاً من الاعتماد على وظيفة واحدة فقط، يمكن أن يُوفر الجمع بين الأدوات أفضل رؤية حول استخدام الذاكرة، مما يساعد في تحسين كفاءة التطبيق ويحقق أداءً أفضل بصفة عامة.
باستخدام المعرفة المكتسبة من هذا المقال، يمكن للمطورين قياس استخدام الذاكرة في Python بدقة أكبر وفهم الأسباب وراء الاختلاف في النتائج، مما يدفعهم لتحقيق تحسينات في تصميم البرمجيات التي يقومون بها.