I understand that int
and uint
are 64bit signed / unsigned integers - just like int64
/ uint64
. And I also understand that int
is not simply an alias for int64
(like byte
-> uint8
is), so int64
would need to be converted to int
and visa versa when applicable. However what are the benefits of using one over the other? Is there any run time performance penalty for using the general types?
Sorry if this is a common question - I had Googled for the answer (and searched on here too) as I'd have thought others might have cropped up before but didn't find anyone answer the question in terms of how they affect performance (if at all), memory usage (I'm guessing not if they're both 64bit integers?) nor how the compiler treats them.
edit: I'm aware that int
/ unit
are 32bit on 32bit architectures. For the sake of brevity and comparing like for like, I was assuming this is a 64bit Golang environment.
int
and uint
are only 64-bit on 64-bit architectures. On 32-bit architectures they are 32 bits.
The general answer is that, unless you need a certain precision, sticking with datatypes that are the same size as a word on the current architecture (e.g. 32 bits on a 32-bit architecture) is typically slightly more efficient.
In addition to int being of "native" size slice and array indices are int and not int64 or int32.
int
and uint
correspond to the maximum possible length of basic Go data structures in a Go implementation and runtime. The length of string
, map[K]T
, []T
and chan T
always fits into an int
, and the capacity of []T
and chan T
always fits into an int
.
An allocation via make
is bound to return an object with length and capacity that always fit into an int
. The built-in function append
returns a slice with length and capacity that never exceed an int
. The length (the number of defined keys) of a map after inserting a new key-value pair always fits into an int
.
The main benefit is that int
and uint
are the smallest (in terms of bitsize) data types which are safe to use in a Go program in conjunction with common Go data types such as slices and maps.
The size of int
is independent from the size of a pointer *T
. The integer type corresponding to *T
is uintptr
. In theory, a Go implementation could choose to map int
to int16
- many Go programs would remain to work correctly, but limiting the size of allocations to 15 bits may be too restrictive and would cause runtime panics.
On 64-bit architectures Go 1.0 has int
and uint
32 bits long, Go 1.1 64 bits long (see Go 1.1 Release Notes). This change will increase the memory usage of some Go programs on 64-bit architectures..
Explicitly using int64
instead of int
in a Go program can make it slower under Go 1.0 and on 32-bit architectures because:
of conversions between int
and int64
the performance of certain CPU instructions, such as division, depends on the size of operands
Explicitly using int64
instead of int
in a Go program can make it faster under Go 1.0 on 64-bit architectures because:
Using uint16
as an index when accessing [1<<16]T
allows the compiler to remove bound checking instructions.