向接口分配int或float会在内部导致块分配吗?

ike

我想知道Go接口的实现方式,以及当我传递int或float64时是否意味着在堆上分配一个块。

是否有可能知道何时暗示分配?

我之所以这样问,是因为我有多种方式来实现程序,并且我倾向于选择一种容易做出先验选择的方式中效率最高的方式

一种设计意味着使用接口传递值,而我传递int,float和nil值。一种可能的设计是也传递包含错误和int值的结构值。但是,如果它在内存分配中“昂贵”,我可以避免这种情况。问题是努力是否值得。

注意:请不要告诉我不要过早优化。我知道这个原则。在某些情况下,您确实想进行优化,那么最好知道如何或如何不实现效率低下的代码。

wasmup

你的标杆,它会告诉你(不MEM allocs这里):

1。

go test -bench=. -benchmem -benchtime=1000000000x
# BenchmarkMethod1-8 1000000000 6.58  ns/op  0 B/op  0 allocs/op
# BenchmarkMethod2-8 1000000000 0.806 ns/op  0 B/op  0 allocs/op

码:

package main

import (
    "testing"
)

func BenchmarkMethod1(b *testing.B) {
    for i := 0; i < b.N; i++ {
        method1(42)
        method1(4.2)
    }
}
func BenchmarkMethod2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        method2(intOrFloat{isInt: true, i: 42})
        method2(intOrFloat{f64: 4.2})
    }
}

func method1(object interface{}) {
    switch v := object.(type) {
    case int:
        i = v
    case float64:
        f64 = v
    }
}

func method2(object intOrFloat) {
    if object.isInt {
        i = object.i
    } else {
        f64 = object.f64
    }
}

type intOrFloat struct {
    isInt bool
    i     int
    f64   float64
}

var i int
var f64 float64

go test -bench=. -benchmem -benchtime=100x
# BenchmarkMethod1-8  100  4202731 ns/op  0 B/op  0 allocs/op
# BenchmarkMethod2-8  100  3412604 ns/op  0 B/op  0 allocs/op

码:

package main

import (
    "testing"
)

func BenchmarkMethod1(b *testing.B) {
    for i := 0; i < b.N; i++ {
        outputInt = outputInt[:0]
        outputf64 = outputf64[:0]
        for i := 0; i < max; i++ {
            switch v := inputIface[i].(type) {
            case int:
                outputInt = append(outputInt, v)
            case float64:
                outputf64 = append(outputf64, v)
            }
        }
    }
}
func BenchmarkMethod2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        outputInt = outputInt[:0]
        outputf64 = outputf64[:0]
        for i := 0; i < max; i++ {
            if inputStruct[i].isInt {
                outputInt = append(outputInt, inputStruct[i].i)
            } else {
                outputf64 = append(outputf64, inputStruct[i].f64)
            }
        }
    }
}

type intOrFloat struct {
    isInt bool
    i     int
    f64   float64
}

func init() {
    for i := 0; i < max; i++ {
        if i%2 == 0 {
            inputIface[i] = float64(i)
            inputStruct[i] = intOrFloat{f64: float64(i)}
        } else {
            inputIface[i] = int(i)
            inputStruct[i] = intOrFloat{isInt: true, i: i}
        }
    }
}

const max = 1_000_000

var inputIface = make([]interface{}, max)
var inputStruct = make([]intOrFloat, max)

var outputf64 = make([]float64, 0, max)
var outputInt = make([]int, 0, max)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用“ =”在内部用char数组分配结构?

接口如何在内部工作?

在C#中,默认==操作员授权会在内部调用ReferenceEquals吗?

pool.map()如何在内部分配工作?

分配者:标准容器应如何在内部工作?

子类构造函数无法在内部分配给readonly变量

JS:如果陈述不起作用,则在内部分配

如果我尝试在内部网络中运行,为什么“端口已分配”?

pthreads 在内部忙着等待吗?

java接口如何在内部实现?(vtables?)

golang的“范围接口”如何在内部运行?

使用块防止对象在内部处理

从块内部进行变量分配

部署EntityConnection也在内部部署DbConnection吗?

您可以在内部托管 bitbucket 管道吗?

从plsql块向数组分配值

堆分配的对象会在堆栈上分配其成员吗?

我应该在内部或外部尺寸上声明一个带有GPU块号的双精度数组吗?

在内部调用函数

在内部渲染图标

Traeffik 不会在内部将传入的 443 映射到端口 80

Mkdirs不会在内部存储中创建文件夹(Android)

即使条件为假,循环也会在内部运行代码

为什么不能在内部接口中使用泛型?

比较器接口如何工作以及如何在内部调用compare()方法

为什么在内部类中C#找不到动态的接口方法?

如果(false == true)在内部抛出异常时执行块

Objective-C-传递给子块的父函数的参数在内部未更改

div内联块元素在内部插入另一个元素时中断