Дополнительное выделение при возврате интерфейса {} вместо int64

У меня есть функция, которая генерирует случайный int64 и возвращает его как interface{} как это:

func Val1(rnd rand.Source) interface{} {
 return rnd.Int63() 
} 

Теперь рассмотрим эту функцию, которая делает то же самое, но возвращает int64

func Val2(rnd rand.Source) int64 {
 return rnd.Int63()
}

Я сравнил две функции с этим (go test -bench=. -benchmem):

func BenchmarkVal1(b *testing.B) {
    var rnd = rand.NewSource(time.Now().UnixNano())
    for n := 0; n < b.N; n++ {
        Val1(rnd)
    }
}

func BenchmarkVal2(b *testing.B) {
    var rnd = rand.NewSource(time.Now().UnixNano())
    for n := 0; n < b.N; n++ {
        Val2(rnd)
    }
}

и получил следующие результаты:

BenchmarkVal1-4    50000000         32.4 ns/op         8 B/op          1 allocs/op
BenchmarkVal2-4    200000000        7.47 ns/op         0 B/op          0 allocs/op

Откуда берется дополнительное распределение в Val1() родом из? Можно ли этого избежать при возврате interface{}?

1 ответ

Решение

Значением интерфейса является обертка под капотом, пара конкретных значений, хранящихся в значении интерфейса, и его дескриптор типа.

Прочитайте это для получения дополнительной информации: Законы Отражения # Представление интерфейса

Так что если вы хотите вернуть значение interface{} тип, interface{} значение будет создано неявно (если возвращаемое значение уже не того типа), которое будет содержать целое число и его дескриптор типа, обозначающий int64 тип. Вы не можете избежать этого.

interface{} это специальный тип интерфейса (имеющий 0 методов). Его значение составляет всего 8 байтов, как вы видите на выходе теста. Другие типы интерфейса имеют больший размер (double), поскольку они также должны идентифицировать статический набор методов типа интерфейса (помимо динамического типа и значения).

Также обязательно ознакомьтесь с этим информативным ответом: Go: Что означает интерфейс {}?

Если вы хотите получить больше информации о реализации / внутренностях, я рекомендую этот пост: как работают интерфейсы в Golang

Другие вопросы по тегам