GoDasturchi
Helping the Compiler

Helping the Compiler

Kompilyatorga yordam berish

Benchmark sizga ajratma qiladigan qizigan yo'lni ko'rsatgach, kutmagan heap trafigingizning aksariyatini uchta andaza tashkil qiladi.

Keng tarqalgan heap tuzoqlari

1. Chaqiruvchi faqat o'qiydigan pointerni qaytarish

example.go
func parseConfig() *Config { return &Config{...} }  // heapga chiqib ketadi
func parseConfig() Config  { return Config{...} }    // stackda qoladi

Pointer freymni tark etadi, shuning uchun Config u bilan birga o'la olmaydi. Chaqiruvchi natijadan faqat maydonlarni o'qisa, *ni olib tashlang va qiymatni qaytaring. Bu uchtadan eng arzon tuzatish: pointer hech qachon hech qanday ish qilmayotgan edi.

2. Interfeys kutilgan joyga qiymat uzatish

example.go
log.Printf("%s took %dms", name, ms)                     // name va ms chiqib ketadi

Konkret qiymatni interface{} (yoki any) kutilgan joyga uzatish uni qutiga soladi (boxing): Go qiymatni heapga nusxalaydi, shunda interfeys unga pointer ushlab turishi mumkin.

fmt.Sprintf, log.Printf, va json.Marshal barchasi ...interface{} qabul qiladi, shuning uchun ularning argumentlari shu tarzda chiqib ketadi. Har bir so'rovda ishlaydigan yo'lda, bu ajratmalar to'planadi. Satrni o'zingiz strings.Builder va strconv.Itoa bilan yasang, ular konkret turlarni qabul qiladi va hech narsani qutiga solmaydi.

3. Goroutine ichida o'zgaruvchini ushlab olish

example.go
go func() { upload(payload) }()                            // payload chiqib ketadi

Goroutine bu funksiya qaytgandan keyin ham ishlashda davom etishi mumkin, shuning uchun payload freymdan uzoqroq yashashi kerak. Buning o'rniga uni argument sifatida bering, shunda uning umri yopilishning emas, goroutine'ningdek bo'ladi:

example.go
go func(p []byte) { upload(p) }(payload)

>_ Exercise

collect so'rov kechikishlari to'plamini bitta Statsga jamlaydi. U *Stats qaytaradi, shuning uchun har bir to'plam heapda bittadan ajratadi. Chaqiruvchi faqat maydonlarni o'qiydi, shuning uchun o'sha pointer hech narsa bermaydi: Statsni qiymat sifatida qaytaring va u stackda qoladi.

Tuzoq — *Stats orqali yozadigan accumulate yordamchisi. Shunchaki *ni olib tashlab bo'lmaydi. Manzil qayerda olinishini hal qilishingiz kerak.

Vazifangiz

collectni avvalgi natija bilan bir xil, Statsni qiymat sifatida qaytaradigan qilib qayta tuzing.

Talablar

  • collectning qaytish turini *Statsdan Statsga o'zgartiring.
  • Natijani new(Stats) o'rniga var s Stats bilan yasang.
  • accumulatega &sni bering, so'ng sni qaytaring.
  • accumulatega tegmang. O'zgartiradigan yordamchiga pointer kerak.

Ishingizni tekshirish

Run faqat dastur natijasini chop etadi. Submit go build -gcflags="-m" bilan yig'adi va escape-analysis diagnostikasini ko'rsatadi. PASS — Stats chiqib ketmagani va natija hali ham count=4 total=495 max=200 ekanligini bildiradi.

Stuck? Reveal a hint to help you.

Hints (0/4)

Key Takeaway

Key Takeaway:

Eng arzon pointer — siz olmagan pointer. Chaqiruvchiga pointer semantikasi kerak bo'lmaganda, qiymatni qaytaring va escape analysis'ning o'zi stackka qo'yishiga ruxsat bering.

NEXT UP

Project: Feature Flags

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Helping the Compiler

Kompilyatorga yordam berish

Benchmark sizga ajratma qiladigan qizigan yo'lni ko'rsatgach, kutmagan heap trafigingizning aksariyatini uchta andaza tashkil qiladi.

Keng tarqalgan heap tuzoqlari

1. Chaqiruvchi faqat o'qiydigan pointerni qaytarish

example.go
func parseConfig() *Config { return &Config{...} }  // heapga chiqib ketadi
func parseConfig() Config  { return Config{...} }    // stackda qoladi

Pointer freymni tark etadi, shuning uchun Config u bilan birga o'la olmaydi. Chaqiruvchi natijadan faqat maydonlarni o'qisa, *ni olib tashlang va qiymatni qaytaring. Bu uchtadan eng arzon tuzatish: pointer hech qachon hech qanday ish qilmayotgan edi.

2. Interfeys kutilgan joyga qiymat uzatish

example.go
log.Printf("%s took %dms", name, ms)                     // name va ms chiqib ketadi

Konkret qiymatni interface{} (yoki any) kutilgan joyga uzatish uni qutiga soladi (boxing): Go qiymatni heapga nusxalaydi, shunda interfeys unga pointer ushlab turishi mumkin.

fmt.Sprintf, log.Printf, va json.Marshal barchasi ...interface{} qabul qiladi, shuning uchun ularning argumentlari shu tarzda chiqib ketadi. Har bir so'rovda ishlaydigan yo'lda, bu ajratmalar to'planadi. Satrni o'zingiz strings.Builder va strconv.Itoa bilan yasang, ular konkret turlarni qabul qiladi va hech narsani qutiga solmaydi.

3. Goroutine ichida o'zgaruvchini ushlab olish

example.go
go func() { upload(payload) }()                            // payload chiqib ketadi

Goroutine bu funksiya qaytgandan keyin ham ishlashda davom etishi mumkin, shuning uchun payload freymdan uzoqroq yashashi kerak. Buning o'rniga uni argument sifatida bering, shunda uning umri yopilishning emas, goroutine'ningdek bo'ladi:

example.go
go func(p []byte) { upload(p) }(payload)

>_ Exercise

collect so'rov kechikishlari to'plamini bitta Statsga jamlaydi. U *Stats qaytaradi, shuning uchun har bir to'plam heapda bittadan ajratadi. Chaqiruvchi faqat maydonlarni o'qiydi, shuning uchun o'sha pointer hech narsa bermaydi: Statsni qiymat sifatida qaytaring va u stackda qoladi.

Tuzoq — *Stats orqali yozadigan accumulate yordamchisi. Shunchaki *ni olib tashlab bo'lmaydi. Manzil qayerda olinishini hal qilishingiz kerak.

Vazifangiz

collectni avvalgi natija bilan bir xil, Statsni qiymat sifatida qaytaradigan qilib qayta tuzing.

Talablar

  • collectning qaytish turini *Statsdan Statsga o'zgartiring.
  • Natijani new(Stats) o'rniga var s Stats bilan yasang.
  • accumulatega &sni bering, so'ng sni qaytaring.
  • accumulatega tegmang. O'zgartiradigan yordamchiga pointer kerak.

Ishingizni tekshirish

Run faqat dastur natijasini chop etadi. Submit go build -gcflags="-m" bilan yig'adi va escape-analysis diagnostikasini ko'rsatadi. PASS — Stats chiqib ketmagani va natija hali ham count=4 total=495 max=200 ekanligini bildiradi.

Stuck? Reveal a hint to help you.

Hints (0/4)

Key Takeaway

Key Takeaway:

Eng arzon pointer — siz olmagan pointer. Chaqiruvchiga pointer semantikasi kerak bo'lmaganda, qiymatni qaytaring va escape analysis'ning o'zi stackka qo'yishiga ruxsat bering.

NEXT UP

Project: Feature Flags