2016-03-21 37 views
5

Tôi tình cờ gặp một điều thú vị trong khi kiểm tra hiệu năng cấp phát bộ nhớ trong GO.hiệu suất phân bổ slice golang

package main 

import (
     "fmt" 
     "time" 
    ) 

func main(){ 
    const alloc int = 65536 
    now := time.Now() 
    loop := 50000 
    for i := 0; i<loop;i++{ 
     sl := make([]byte, alloc) 
     i += len(sl) * 0 
    } 
    elpased := time.Since(now) 
    fmt.Printf("took %s to allocate %d bytes %d times", elpased, alloc, loop) 
} 

Tôi đang chạy này trên một Core-i7 2600 với phiên bản đi 1,6 64bit (cũng tương tự kết quả trên 32bit) và 16GB RAM (trên WINDOWS 10) nên khi alloc là 65536 (chính xác 64K) nó chạy trong 30 giây (!!!!). Khi phân bổ là 65535 phải mất ~ 200ms. Ai đó có thể giải thích điều này cho tôi được không? Tôi đã thử cùng một mã ở nhà với lõi i7-920 @ 3.8GHZ nhưng nó không hiển thị kết quả tương tự (cả hai mất khoảng 200ms). Bất cứ ai cũng có một ý tưởng gì đang xảy ra?

+1

Để thêm nhiều biến thể hơn, hãy thử mã của bạn trên Windows 7 (Go 1.6, 64 bit), tôi nhận được 17 giây cho dù 'alloc' là' 65536' hoặc '65535'. – icza

+0

Tôi không phải là một chuyên gia về phân bổ nội bộ, nhưng tôi chỉ muốn đề cập đến việc phân bổ một slice của 65536 byte thực sự phân bổ cộng với 2 số nguyên (các 'len' và' cap' quầy), do đó, thực sự hơn 64KB. – Elwinar

+2

Để thêm thông tin thêm cho vấn đề, tôi chạy mã trên Archlinux của tôi (i7-4720HQ @ 2.60GHz), và phải mất liên tục ~ 600ms. Bạn nên cố gắng sử dụng công cụ lược tả trên thiết lập mất nhiều thời gian. Nó thực sự là một trường hợp tốt để bắt đầu học nó nếu bạn không biết nó đã. – Elwinar

Trả lời

4

Đặt GOGC = tắt hiệu suất được cải thiện (xuống dưới 100 mili giây). Tại sao? becaue của escape analysis. Khi bạn xây dựng với go build -gcflags -m trình biên dịch sẽ in mọi phân bổ thoát ra khỏi heap. Nó thực sự phụ thuộc vào máy của bạn và phiên bản trình biên dịch GO nhưng khi trình biên dịch quyết định rằng việc phân bổ sẽ chuyển sang đống nó có nghĩa là 2 điều: 1. phân bổ sẽ mất nhiều thời gian hơn (vì "phân bổ" trên ngăn xếp chỉ là 1 hướng dẫn cpu) 2. GC sẽ phải dọn dẹp bộ nhớ đó sau đó - tốn nhiều thời gian CPU hơn cho máy của tôi, việc phân bổ 65536 byte thoát tới heap và 65535 thì không. đó là lý do tại sao 1 byte thay đổi toàn bộ quá trình từ 200ms thành 30 giây. Tuyệt vời ..

Các vấn đề liên quan