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

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

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

ابدأ الدورة

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

\n\n

عندما يبدأ مشروع Go الخاص بك في التباطؤ، أو استهلاك الكثير من الذاكرة، أو العمل بشكل غير مستقر، يظهر سؤال منطقي: "أين نقطة الاختناق؟" نادرًا ما تساعد التخمينات البديهية - فأنت بحاجة إلى بيانات دقيقة. تحليل الأداء (profiling) هو عملية جمع مقاييس حول أداء البرنامج: مقدار الوقت الذي تستغرقه كل دالة، مقدار الذاكرة المخصصة، عدد مرات استدعاء جامع القمامة. في هذه المقالة، سنشرح كيفية استخدام الأدوات المدمجة في Go (pprof و trace) للعثور على مشكلات الأداء وإصلاحها بسرعة.

\n\n

ما هو تحليل الأداء ولماذا هو ضروري؟

\n\n

تحليل الأداء يشبه الأشعة السينية لرمزك. لا ترى فقط "البرنامج يعمل ببطء"، بل ترى أرقامًا محددة: الدالة parseData() تستهلك 40% من الوقت، والدالة loadConfig() تخصص 2 جيجابايت من الذاكرة. بالنسبة لـ Go، هناك عدة أنواع من ملفات التحليل:

\n\n
    \n
  • ملف CPU - يوضح أي الدوال تستهلك وقت المعالج.
  • \n
  • ملف الذاكرة (heap) - يوضح أي الدوال تخصص الذاكرة وأين توجد الكائنات.
  • \n
  • ملف Goroutine - يوضح عدد الغوروتينات النشطة وحالتها.
  • \n
  • ملف Block - يوضح أين يتم حظر الغوروتينات على الميوتكسات أو القنوات.
  • \n
  • ملف Mutex - يوضح التنافس على الميوتكسات.
  • \n
\n\n

للمبتدئين، الأكثر فائدة هو تحليل أداء CPU والذاكرة. فهما يعطيان 80% من الإجابات على سؤال "لماذا يتباطأ الكود".

\n\n

أداة pprof: محلل الأداء المدمج في Go

\n\n

تأتي Go مع حزمة مدمجة net/http/pprof. تضيف نقاط نهاية إلى خادم HTTP الخاص بك يمكن من خلالها أخذ ملفات التحليل. دعنا نلقي نظرة على مثال أساسي.

\n\n

الخطوة 1: ربط pprof بالتطبيق

\n\n
package main\n\nimport (\n    "fmt"\n    "log"\n    "net/http"\n    _ "net/http/pprof" // ربط المحلل\n    "time"\n)\n\nfunc main() {\n    // تشغيل الخادم على المنفذ 8080\n    go func() {\n        log.Println(http.ListenAndServe("localhost:8080", nil))\n    }()\n\n    // منطق الأعمال "الثقيل" الخاص بنا\n    for i := 0; i < 100; i++ {\n        go heavyTask(i)\n    }\n\n    // انتظار الانتهاء\n    time.Sleep(10 * time.Second)\n    fmt.Println("Done")\n}\n\nfunc heavyTask(id int) {\n    // محاكاة عمل ثقيل\n    for i := 0; i < 1000000; i++ {\n        _ = i * i\n    }\n    fmt.Printf("Task %d finished\\n", id)\n}\n
\n\n

بعد تشغيل التطبيق، افتح المتصفح على العنوان http://localhost:8080/debug/pprof/. سترى واجهة ويب تحتوي على روابط لملفات التحليل.

\n\n

الخطوة 2: أخذ ملف CPU

\n\n

أسهل طريقة هي استخدام سطر الأوامر. قم بتشغيل:

\n\n
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
\n\n

سيقوم هذا الأمر بجمع ملف CPU لمدة 30 ثانية. بعد الانتهاء، سيتم فتح وحدة تحكم تفاعلية لـ pprof. اكتب top لرؤية الدوال الأكثر "سخونة":

\n\n
(pprof) top\nShowing nodes accounting for 1.50s, 100% of 1.50s total\n      flat  flat%   sum%        cum   cum%\n     1.50s   100%   100%      1.50s   100%  main.heavyTask\n         0     0%   100%      1.50s   100%  runtime.main\n
\n\n

هنا flat هو الوقت المستغرق مباشرة داخل الدالة، و cum هو الوقت بما في ذلك استدعاءات الدوال الفرعية. في مثالنا، 100% من الوقت يذهب إلى heavyTask.

\n\n

الخطوة 3: التصور عبر واجهة الويب

\n\n

لتحليل أكثر وضوحًا، استخدم الوضع الرسومي:

\n\n
go tool pprof -http=:8081 http://localhost:8080/debug/pprof/profile?seconds=30
\n\n

سيتم فتح المتصفح مع رسم بياني تفاعلي للاستدعاءات. كلما كانت الكتلة أكبر وأكثر احمرارًا، زادت الموارد التي تستهلكها. هذه طريقة ممتازة للعثور بسرعة على الدوال "السمينة".

\n\n

تحليل أداء الذاكرة:

المدونات

توصيات الكتب