Go प्रदर्शन: कोड को प्रोफाइल और तेज़ कैसे करें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

आपका Go कोड धीमा चल रहा है? अब हुड के नीचे झांकने का समय है

\n\n

आपने Go में एक सर्विस लिखी है। वह चल रही है। लेकिन जब लोड 10,000 RPS तक पहुंचता है, तो सर्वर 'हांफने' लगता है। यह स्थिति जानी-पहचानी है? Go अपनी 'आउट-ऑफ-द-बॉक्स' परफॉरमेंस के लिए मशहूर है, लेकिन इस खूबसूरत भाषा में भी कुछ छिपे हुए नुकसान हैं। गोरूटीन लीक, अकुशल मेमोरी मैनेजमेंट, अनावश्यक एलोकेशन - ये सब स्पीड को मार देते हैं।

\n\n

इस लेख में, हम जानेंगे कि Go प्रोफाइलिंग कैसे बाधाओं को खोजने में मदद करती है, और Go एप्लिकेशन ऑप्टिमाइज़ेशन की विशिष्ट तकनीकें दिखाएंगे। आप सीखेंगे कि कैसे बिल्ट-इन टूल्स pprof और go test -bench का उपयोग करके अपने एप्लिकेशन को रॉकेट में बदल सकते हैं। चलिए शुरू करते हैं!

\n\n

प्रोफाइलर टूलकिट: pprof और trace

\n\n

Go परफॉरमेंस एनालिसिस के लिए दो शक्तिशाली टूल प्रदान करता है: pprof (CPU, मेमोरी, लॉक प्रोफाइलिंग) और go tool trace (कंकरेंसी और GC इवेंट्स का विश्लेषण)।

\n\n

HTTP सर्वर में pprof एम्बेड करना

\n\n

प्रोफाइलिंग शुरू करने का सबसे आसान तरीका है अपने सर्वर में net/http/pprof जोड़ना। इसमें सिर्फ एक इम्पोर्ट लाइन लगेगी:

\n\n
import (\n    _ "net/http/pprof"\n    "net/http"\n)\n\nfunc main() {\n    http.ListenAndServe(":8080", nil)\n}
\n\n

अब /debug/pprof/ पते पर प्रोफाइल उपलब्ध हैं। 30 सेकंड के लिए CPU प्रोफाइल लेने के लिए, यह चलाएं:

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

डेटा इकट्ठा होने के बाद, एक इंटरैक्टिव कंसोल खुलेगा। top15 कमांड सबसे हॉट फंक्शन दिखाएगा:

\n\n
(pprof) top15\nShowing nodes accounting for 3.50s, 87.50% of 4.00s total\n      flat  flat%   sum%        cum   cum%\n     1.20s 30.00% 30.00%      1.50s 37.50%  main.heavyComputation
\n\n

main.heavyComputation देख रहे हैं? यह हमारा ऑप्टिमाइज़ेशन उम्मीदवार है। विज़ुअलाइज़ेशन के लिए web का उपयोग करें (यदि Graphviz इंस्टॉल है) - आपको एक कॉल ग्राफ मिलेगा।

\n\n

मेमोरी प्रोफाइलिंग: लीक ढूंढना

\n\n

Go में मेमोरी लीक अक्सर गोरूटीन लीक या बड़े ऑब्जेक्ट्स के भूले हुए रेफरेंस होते हैं। हीप प्रोफाइल लें:

\n\n
go tool pprof http://localhost:8080/debug/pprof/heap
\n\n

alloc_objects कमांड दिखाएगा कि कौन से फंक्शन सबसे ज्यादा ऑब्जेक्ट बना रहे हैं:

\n\n
(pprof) alloc_objects\n    2.50GB  100%  100%      2.50GB  100%  main.createLargeSlice
\n\n

इस तरह हमने एक फंक्शन ढूंढा जो 2.5 GB मेमोरी आवंटित कर रहा है! हो सकता है कि वहां एक बड़ा स्लाइस बन रहा हो, जिसे sync.Pool का उपयोग करके पुन: उपयोग किया जा सकता है।

\n\n

बेंचमार्क लिखना: ऑप्टिमाइज़ेशन की ओर पहला कदम

\n\n

ऑप्टिमाइज़ करने से पहले, मापना ज़रूरी है। Go बेंचमार्क अलग-अलग फंक्शन की परफॉरमेंस मापने का मानक टूल है।

\n\n

उदाहरण: स्ट्रिंग कॉन्केटनेशन की तुलना

\n\n

मान लीजिए हम लूप में स्ट्रिंग्स जोड़ रहे हैं। खराब तरीका:

\n\n
func ConcatSlow(parts []string) string {\n    result := ""\n    for _, p := range parts {\n        result += p\n    }\n    return result\n}
\n\n

अच्छा तरीका है strings.Builder का उपयोग करना:

\n\n
func ConcatFast(parts []string) string {\n    var b strings.Builder\n    for _, p := range parts {\n        b.WriteString(p)\n    }\n    return b.String()\n}
\n\n

बेंचमार्क लिखें (फ़ाइल concat_test.go):

\n\n
func BenchmarkConcatSlow(b *testing.B) {\n    parts := []string{"Hello", " ", "World", "!", " ", "From", " ", "Go"}\n    for i := 0; i < b.N; i++ {\n        ConcatSlow(parts)\n    }\n}\n\nfunc BenchmarkConcatFast(b *testing.B) {\n    parts := []string{"Hello", " ", "World", "!", " ", "From", " ", "Go"}\n    for i := 0; i < b.N; i++ {\n        ConcatFast(parts)\n    }\n}
\n\n

चलाएं:

\n\n
go test -bench=. -benchmem
\n\n

परिणाम:

\n\n
BenchmarkConc                

ब्लॉग

पुस्तक अनुशंसाएँ