2015-07-19 29 views
5

Ben bir yapı olduğunu varsayalım:Yapı boyutunu ve içeriğini golang olarak bayt cinsinden nasıl alabilirim?

type ASDF struct { 
    A uint64 
    B uint64 
    C uint64 
    D uint64 
    E uint64 
    F string 
} 

O yapı bir dilim oluşturmak: a := []ASDF{}

yapmam yapının o dilim işlemleri (içeriği değişebilir ekleme/kaldırma/güncelleme yapılar) ; Dilimin ve içeriğinin toplam boyutu bayt cinsinden (bellek için) nasıl alabilirim? Bunu yapmak için bir yerleşik var mı yoksa unsafe.Sizeof ve len her dizeyi kullanarak bir hesaplamayı manuel olarak çalıştırmam gerekiyor mu?

+0

Hızlı soru, 'ASDF' sabit boyut yapısına bir değil? O zaman sadece 'ASDF' yapısal işaretçisinin boyutunu len (a) 'ile çarpabilirsiniz. Aynı büyüklüğü yalnızca dilime ekleyebileceğiniz gibi mi? Yoksa dilimin nasıl çalıştığını yanlış mı anladım? – Anzel

+0

Ancak "string" alanında bir sorun olurdu. –

cevap

6

Çöp toplayıcı ve diğer genel masraflar hariç tüm belleğin boyutunu toplayın. Örneğin,

package main 

import (
    "fmt" 
    "unsafe" 
) 

type ASDF struct { 
    A uint64 
    B uint64 
    C uint64 
    D uint64 
    E uint64 
    F string 
} 

func (s *ASDF) size() int { 
    size := int(unsafe.Sizeof(*s)) 
    size += len(s.F) 
    return size 
} 

func sizeASDF(s []ASDF) int { 
    size := 0 
    s = s[:cap(s)] 
    size += cap(s) * int(unsafe.Sizeof(s)) 
    for i := range s { 
     size += (&s[i]).size() 
    } 
    return size 
} 

func main() { 
    a := []ASDF{} 

    b := ASDF{} 
    b.A = 1 
    b.B = 2 
    b.C = 3 
    b.D = 4 
    b.E = 5 
    b.F = "ASrtertetetetetetetDF" 
    fmt.Println((&b).size()) 
    a = append(a, b) 

    c := ASDF{} 
    c.A = 10 
    c.B = 20 
    c.C = 30 
    c.D = 40 
    c.E = 50 
    c.F = "ASetDF" 
    fmt.Println((&c).size()) 
    a = append(a, c) 

    fmt.Println(len(a)) 
    fmt.Println(cap(a)) 
    fmt.Println(sizeASDF(a)) 
} 

Çıktı: tüm değişken türleri beyan beri

69 
54 
2 
2 
147 

http://play.golang.org/p/5z30vkyuNM

1

Herhangi bir sonuç almak istiyorsanız, unsafe.Sizeof'un buraya gitmenin yolu olduğunu düşünüyorum. Bir yapının bellek içi boyutu, güvenmeniz gereken bir şey değildir. unsafe.Sizeof sonucunun bile hatalı olduğuna dikkat edin: Çalışma zamanı, çöp toplama konusunda yardımcı olamayacağınız verilere başlık ekleyebilir.

Özel örneğiniz için (bir önbellek boyutu bulmak), birçok işlemci için makul olan statik bir boyutta gitmenizi öneririm. Hemen hemen tüm durumlarda, bu tür mikro optimizasyonlar kendi kendine ödeme yapmayacaktır.

+0

['len (...)'] (http://golang.org/pkg/builtin/#len) işlevi yalnızca diziler, dizeler, dilimler ve kanallarla çalışır gibi görünüyor. Structs = ile yardım yok = ( – maerics

+0

@maerics Sadece neyi başarmaya çalıştığınıza dair daha iyi bir anlayışa sahip olmak için, bu bilginin ne işe yarar olduğuna inanıyorsunuz? – fuz

+0

@FUZxxl: hiçbir fikir, OP'ye sor =) Sadece yorum yapıyorum fıstık galerisinden – maerics

İlgili konular