• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            戰(zhàn)魂小筑

            討論群:309800774 知乎關(guān)注:http://zhihu.com/people/sunicdavy 開源項(xiàng)目:https://github.com/davyxu

               :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評(píng)論 :: 0 Trackbacks

            測(cè)試用例

            我們對(duì)Golang的結(jié)構(gòu)體變量賦值, 以及單參數(shù)函數(shù)調(diào)用進(jìn)行反射和native操作的測(cè)試

             

            package main

             

            import (

            "reflect"

            "testing"

            )

             

            type data struct {

            Hp int

            }

             

            const AssignTimes = 100000000

             

            func TestNativeAssign(t *testing.T) {

             

            v := data{Hp: 2}

             

            for i := 0; i < AssignTimes; i++ {

            v.Hp = 3

            }

             

            }

             

            func TestReflectAssign(t *testing.T) {

             

            v := data{Hp: 2}

             

            vv := reflect.ValueOf(&v).Elem()

             

            f := vv.FieldByName("Hp")

             

            for i := 0; i < AssignTimes; i++ {

             

            f.SetInt(3)

            }

             

            }

             

            func TestReflectFindFieldAndAssign(t *testing.T) {

             

            v := data{Hp: 2}

             

            vv := reflect.ValueOf(&v).Elem()

             

            for i := 0; i < AssignTimes; i++ {

             

            vv.FieldByName("Hp").SetInt(3)

            }

             

            }

             

            func foo(v int) {

             

            }

             

            const CallTimes = 100000000

             

            func TestNativeCall(t *testing.T) {

            for i := 0; i < CallTimes; i++ {

             

            foo(i)

            }

            }

             

            func TestReflectCall(t *testing.T) {

             

            v := reflect.ValueOf(foo)

             

            for i := 0; i < CallTimes; i++ {

             

            v.Call([]reflect.Value{reflect.ValueOf(2)})

            }

            }

            性能測(cè)試數(shù)據(jù)

            === RUN TestNativeAssign
            — PASS: TestNativeAssign (0.03s)
            === RUN TestReflectAssign
            — PASS: TestReflectAssign (0.41s)
            === RUN TestReflectFindFieldAndAssign
            — PASS: TestReflectFindFieldAndAssign (9.86s)
            === RUN TestNativeCall
            — PASS: TestNativeCall (0.03s)
            === RUN TestReflectCall
            — PASS: TestReflectCall (21.46s)

            測(cè)試評(píng)測(cè)

            • 在結(jié)構(gòu)體變量賦值測(cè)試用例中, 我們發(fā)現(xiàn)TestReflectFindFieldAndAssign賦值格外的耗時(shí). 分析性能點(diǎn)在FieldByName這個(gè)函數(shù)上, 我們查了下底層如何實(shí)現(xiàn)的:

            // FieldByName returns the struct field with the given name

            // and a boolean to indicate if the field was found.

            func (t *structType) FieldByName(name string) (f StructField, present bool) {

            // Quick check for top-level name, or struct without anonymous fields.

            hasAnon := false

            if name != "" {

            for i := range t.fields {

            tf := &t.fields[i]

            if tf.name == nil {

            hasAnon = true

            continue

            }

            if *tf.name == name {

            return t.Field(i), true

            }

            }

            }

            if !hasAnon {

            return

            }

            return t.FieldByNameFunc(func(s string) bool { return s == name })

            }

            各位看官必須吐槽用for來遍歷獲取數(shù)據(jù), 但冷靜下來分析. 這樣做無可厚非.
            試想如果reflect包在我們使用ValueOf時(shí)使用map緩沖好一個(gè)結(jié)構(gòu)體所有字段的訪問數(shù)據(jù)后, 肯定訪問指定字段速度會(huì)很快
            但是, 以空間換速度的需求其實(shí)最多滿足了1%的需求.
            同樣的例子是圖形API里訪問Shader變量的方法, 總是默認(rèn)使用字符串獲取, 速度很慢. 當(dāng)你想快速訪問時(shí), 請(qǐng)?zhí)崆鞍葱杈彺孀侄?br>那么, Golang使用的也是這樣的思路. 雖然暴力了一點(diǎn), 但是能夠讓程序跑對(duì), 性能優(yōu)化的東西放在之后來做, 緩沖下就可以解決

            • 在調(diào)用測(cè)試用例中, 毫無懸念的, 調(diào)用速度很慢
              因此, 我們?cè)谄綍r(shí)使用反射時(shí), 盡量偏向于反射變量緩沖存在下的變量賦值或者獲取
              而調(diào)用的需求盡量減少, 如果有g(shù)oroutine存在的情況下, 則不必太多擔(dān)心.
            2020久久精品国产免费| 久久精品国产99国产精品导航| 久久精品亚洲日本波多野结衣| 久久精品亚洲中文字幕无码麻豆| 国产精品久久久久影院嫩草| 一级做a爱片久久毛片| 久久久久亚洲AV无码专区桃色| 少妇熟女久久综合网色欲| 久久久久AV综合网成人| 国产午夜精品久久久久九九| 一本久道久久综合狠狠躁AV| 97超级碰碰碰久久久久| 欧美日韩中文字幕久久久不卡| 亚洲精品乱码久久久久久久久久久久| 久久久久一区二区三区| 国产成人精品久久| 久久天天躁狠狠躁夜夜2020老熟妇| 亚洲国产另类久久久精品黑人| 韩国三级中文字幕hd久久精品 | 久久这里只有精品首页| 久久久精品免费国产四虎| 日本精品一区二区久久久| 国产精品99久久精品| 狠狠色丁香久久婷婷综合| 久久久久国产一级毛片高清板| 高清免费久久午夜精品| 囯产精品久久久久久久久蜜桃| 久久精品国产亚洲5555| 国产精品狼人久久久久影院| 久久天天躁狠狠躁夜夜网站 | 久久久久久青草大香综合精品| 99久久婷婷免费国产综合精品| 亚洲AV无码一区东京热久久| 久久天天婷婷五月俺也去| 久久人人爽人人爽人人片AV麻豆| 99久久婷婷国产综合精品草原| 久久国产亚洲精品无码| 久久99精品久久只有精品| 97久久精品人妻人人搡人人玩| 久久精品a亚洲国产v高清不卡| 69久久夜色精品国产69 |