تحليل أداء كود Go: إيجاد نقاط الاختناق عمليًا

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا تحليل أداء كود Go أمر لا بد منه

تشتهر التطوير بلغة Go (Golang) بأدائها وكفاءتها. ومع ذلك، حتى أسرع كود يمكن أن يتباطأ إذا لم يتم مراعاة خصائص العمل مع الذاكرة، أو الغوروتينات، أو الإدخال/الإخراج. تحليل الأداء هو عملية جمع بيانات حول تنفيذ البرنامج، مما يسمح بالنظر "تحت الغطاء" وفهم أي الوظائف تستهلك أكبر قدر من وحدة المعالجة المركزية (CPU)، أو الذاكرة، أو الوقت.

في هذه المقالة، سنستعرض الأدوات العملية لتحليل الأداء في Go: pprof، trace، واختبارات الأداء المدمجة. ستتعلم كيفية إيجاد نقاط الاختناق وتحسين الكود من خلال أمثلة واقعية.



1. الأدوات الأساسية لتحليل الأداء في Golang

توفر Go ترسانة قوية لتحليل الأداء مباشرة من الصندوق. دعنا نستعرض ثلاث طرق رئيسية:

  • pprof — تحليل أداء وحدة المعالجة المركزية (CPU)، الذاكرة، الأقفال، والغوروتينات.
  • trace — تتبع الأحداث: إنشاء الغوروتينات، استدعاءات النظام، جمع القمامة (GC).
  • benchmark — اختبار أداء مدمج باستخدام go test -bench.

للبدء مع pprof، يكفي استيراد net/http/pprof في خادم HTTP الخاص بك أو استخدام runtime/pprof لتطبيقات سطر الأوامر (CLI).



1.1. كيفية تشغيل تحليل أداء وحدة المعالجة المركزية (CPU)

أسهل طريقة هي إضافة نقطة نهاية إلى خادم HTTP الخاص بك:

package main

import ( "log" "net/http" _ "net/http/pprof")

func main() { go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() // الكود الرئيسي الخاص بك select {}}

بعد التشغيل، افتح http://localhost:6060/debug/pprof/ — سترى لوحة التحكم. لجمع ملف CPU لمدة 30 ثانية، نفذ:

go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

سيؤدي هذا إلى تحميل البيانات وفتح وحدة تحكم تفاعلية لـ pprof.



2. إيجاد نقاط الاختناق باستخدام pprof: وحدة المعالجة المركزية (CPU) والذاكرة

لنفترض أن لدينا دالة تقوم بمعالجة مصفوفة كبيرة من البيانات. نشتبه في أنها تبطئ الأداء. دعنا نكتب مثالًا اختباريًا ونحلله.



2.1. مثال على كود بطيء

package main

import ( "fmt" "time")

func slowFunction(data []int) int { sum := 0 for _, v := range data { time.Sleep(1 * time.Microsecond) // محاكاة العمل sum += v * v } return sum}

func main() { data := make([]int, 100000) for i := range data { data[i] = i } result := slowFunction(data) fmt.Println(result)}

لنقم بتشغيل تحليل أداء وحدة المعالجة المركزية (CPU):

go run main.go &go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile?seconds=10

سيتم فتح تصور في المتصفح — رسم بياني للاستدعاءات (call graph). يُظهر سمك الحواف مقدار الوقت الذي استغرقته كل دالة. سنرى على الفور أن slowFunction و time.Sleep هما المستهلكان الرئيسيان لوحدة المعالجة المركزية (CPU).



2.2. تحليل الذاكرة (heap profile)

لإيجاد تسربات الذاكرة أو الكائنات التي تشغل مساحة كبيرة جدًا، استخدم:

go tool pprof http://localhost:6060/debug/pprof/heap

في وحدة التحكم التفاعلية، يمكن تنفيذ الأمر top:

(pprof) top10Showing nodes accounting for 80MB, 100% of 80MB total      flat  flat%   sum%        cum   cum%      40MB 50.00% 50.00%       40MB 50.00%  main.slowFunction      20MB 25.00% 75.00%       20MB 25.00%  main.createLargeSlice      20MB 25.00% 100.00%      20MB 25.00%  runtime.makeslice

يوضح هذا أي الدوال تقوم بتخصيص أكبر قدر من الذاكرة. إذا رأيت أن main.slowFunction تخصص 40MB، يجب التفكير في إعادة الهيكلة — على سبيل المثال، استخدام إعادة استخدام الشريحة

المدونات

توصيات الكتب