回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,33 +1,33 @@
## 13.1. unsafe.Sizeof, Alignof 和 Offsetof
unsafe.Sizeof函數返迴操作數在內存中的字大小,參數可以是任意型的表式,但是它併不會對表達式進行求值。一Sizeof函數調用是一個對應uintptr型的常量表式,因此返迴的結果可以用作數組類型的度大小,或者用作算其他的常量。
unsafe.Sizeof函数返回操作数在内存中的字大小,参数可以是任意型的表式,但是它并不会对表达式进行求值。一Sizeof函数调用是一个对应uintptr型的常量表式,因此返回的结果可以用作数组类型的度大小,或者用作算其他的常量。
```Go
import "unsafe"
fmt.Println(unsafe.Sizeof(float64(0))) // "8"
```
Sizeof函數返迴的大小包括數據結構中固定的部分,例如字符串對應結構體中的指和字符串度部分,但是不包含指指向的字符串的容。Go言中非聚合型通常有一固定的大小,管在不同工具下生成的實際大小可能有所不同。考到可移植性,引用型或包含引用型的大小在32位平台上是4個字節在64位平台上是8個字節
Sizeof函数返回的大小包括数据结构中固定的部分,例如字符串对应结构体中的指和字符串度部分,但是不包含指指向的字符串的容。Go言中非聚合型通常有一固定的大小,管在不同工具下生成的实际大小可能有所不同。考到可移植性,引用型或包含引用型的大小在32位平台上是4个字节在64位平台上是8个字节
計算機在加和保存數據時,如果存地址合理地對齊的將會更有效率。例如2字大小的int16型的量地址應該是偶,一4字大小的rune類型變量的地址應該是4的倍,一8字大小的float64、uint64或64-bit指針類型變量的地址應該是8字節對齊的。但是對於再大的地址對齊倍數則是不需要的,使是complex128等大的數據類型最多也是8字節對齊
计算机在加和保存数据时,如果存地址合理地对齐的将会更有效率。例如2字大小的int16型的量地址应该是偶,一4字大小的rune类型变量的地址应该是4的倍,一8字大小的float64、uint64或64-bit指针类型变量的地址应该是8字节对齐的。但是对于再大的地址对齐倍数则是不需要的,使是complex128等大的数据类型最多也是8字节对齐
地址對齊這個因素,一聚合型(結構體或數組)的大小至少是所有字段或元素大小的和,或者更大因可能存在存空洞。存空洞是編譯器自添加的有被使用的存空,用於保證後面每字段或元素的地址相對於結構或數組的開始地址能合理地對齊(譯註:內存空洞可能存在一些隨機數據,可能會對用unsafe包直接操作存的處理産生影)。
地址对齐这个因素,一聚合型(结构体或数组)的大小至少是所有字段或元素大小的和,或者更大因可能存在存空洞。存空洞是编译器自添加的有被使用的存空,用于保证后面每字段或元素的地址相对于结构或数组的开始地址能合理地对齐(译注:内存空洞可能存在一些随机数据,可能会对用unsafe包直接操作存的处理产生影)。
型 | 大小
型 | 大小
----------------------------- | ----
bool | 1個字節
intN, uintN, floatN, complexN | N/8個字節(例如float64是8個字節)
int, uint, uintptr | 1個機器字
*T | 1個機器字
string | 2個機器字(data,len)
[]T | 3個機器字(data,len,cap)
map | 1個機器字
func | 1個機器字
chan | 1個機器字
interface | 2個機器字(type,value)
bool | 1个字节
intN, uintN, floatN, complexN | N/8个字节(例如float64是8个字节)
int, uint, uintptr | 1个机器字
*T | 1个机器字
string | 2个机器字(data,len)
[]T | 3个机器字(data,len,cap)
map | 1个机器字
func | 1个机器字
chan | 1个机器字
interface | 2个机器字(type,value)
Go言的規范併沒有要求一字段的聲明順序和存中的序是一致的,所以理上一個編譯器可以意地重新排列每字段的存位置,然在作本書的時候編譯器還沒有這麽做。下面的三個結構體雖然有着相同的字段,但是第一種寫法比另外的兩個需要多50%的存。
Go言的规范并没有要求一字段的声明顺序和存中的序是一致的,所以理上一个编译器可以意地重新排列每字段的存位置,然在作本书的时候编译器还没有这么做。下面的三个结构体虽然有着相同的字段,但是第一种写法比另外的两个需要多50%的存。
```Go
// 64-bit 32-bit
@@ -36,13 +36,13 @@ struct{ float64; int16; bool } // 2 words 3words
struct{ bool; int16; float64 } // 2 words 3words
```
關於內存地址對齊算法的細節超出了本的范,也不是每一個結構體都需要擔心這個問題,不有效的包可以使數據結構更加緊湊(譯註:未的Go語言編譯器應該會默認優化結構體的順序,然用於應該也能指定具體的內存布局,相同討論請參考 [Issue10014](https://github.com/golang/go/issues/10014) 存使用率和性能都可能受益。
关于内存地址对齐算法的细节超出了本的范,也不是每一个结构体都需要担心这个问题,不有效的包可以使数据结构更加紧凑(译注:未的Go语言编译器应该会默认优化结构体的顺序,然用于应该也能指定具体的内存布局,相同讨论请参考 [Issue10014](https://github.com/golang/go/issues/10014) 存使用率和性能都可能受益。
`unsafe.Alignof`數返迴對應參數的類型需要對齊的倍. 和 Sizeof 似, Alignof 也是返迴一個常量表式, 對應一個常量. 通常情下布爾和數字類型需要對齊到它本身的大小(最多8個字節), 其它的類型對齊到機器字大小.
`unsafe.Alignof`数返回对应参数的类型需要对齐的倍. 和 Sizeof 似, Alignof 也是返回一个常量表式, 对应一个常量. 通常情下布尔和数字类型需要对齐到它本身的大小(最多8个字节), 其它的类型对齐到机器字大小.
`unsafe.Offsetof`數的參數必須是一字段 `x.f`, 然後返迴 `f` 字段相對於 `x` 起始地址的偏移量, 包括可能的空洞.
`unsafe.Offsetof`数的参数必须是一字段 `x.f`, 然后返回 `f` 字段相对于 `x` 起始地址的偏移量, 包括可能的空洞.
13.1 示了一個結構體變量 x 以及其在32位和64位器上的典型的存. 灰色域是空洞.
13.1 示了一个结构体变量 x 以及其在32位和64位器上的典型的存. 灰色域是空洞.
```Go
var x struct {
@@ -52,11 +52,11 @@ var x struct {
}
```
下面示了x和它的三字段調用unsafe包相關函數的計算結果:
下面示了x和它的三字段用unsafe包相关函数的计算结果:
![](../images/ch13-01.png)
32位繫統
32位系统
```
Sizeof(x) = 16 Alignof(x) = 4
@@ -65,7 +65,7 @@ Sizeof(x.b) = 2 Alignof(x.b) = 2 Offsetof(x.b) = 2
Sizeof(x.c) = 12 Alignof(x.c) = 4 Offsetof(x.c) = 4
```
64位繫統
64位系统
```
Sizeof(x) = 32 Alignof(x) = 8
@@ -74,5 +74,5 @@ Sizeof(x.b) = 2 Alignof(x.b) = 2 Offsetof(x.b) = 2
Sizeof(x.c) = 24 Alignof(x.c) = 8 Offsetof(x.c) = 8
```
雖然這幾個函數在不安全的unsafe包但是這幾個函數調用併不是的不安全,特别在需要優化內存空間時它們返迴的結果對於理解原生的存布局很有助。
虽然这几个函数在不安全的unsafe包但是这几个函数调用并不是的不安全,特别在需要优化内存空间时它们返回的结果对于理解原生的存布局很有助。