Improve the reflective performance of Golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed. The reflection of the Golang is very slow. This is related to its API design. In Java, we usually use reflection to do this.
Fieldfield=clazz.getField("hello");field.get(obj1);field.get(obj2);

The type of reflection object obtained is Java.lang.reflect.Field. It can be reused. As long as the different obj is passed in, the corresponding field on this obj can be obtained. But Golang's reflection is not designed like this.

type_ := reflect.TypeOf(obj)field, _ := type_.FieldByName("hello")

The Field object to be taken out here is reflect. The Structfield type, but it has no way to get the value on the corresponding object. If you want to take a value, you have to use a different set of reflections on object instead of type.

type_ := reflect.ValueOf(obj)fieldValue := type_.FieldByName("hello")

The Fieldvalue type that is taken out here is reflect. Value, which is a concrete value, not a reusable reflection object.

It's a pain in the egg! the reflect of malloc is required for each reflection. The value struct body. How can Golang's reflective performance be fast?

The Jsoniter is a Golang-based JSON parser that is implemented by reflection. Its implementation principle is to use reflect. Type the information to be reflected directly, without relying on reflect. ValueOf. How is it implemented?

Structural body

Solve a small problem first. How to use reflect. Structfield gets the value on the object?

The corresponding code is in: Go/feature_reflect_object.go at Master Json-iterator/go GitHub

fieldPtr := uintptr(structPtr) + field.Offset

in reflect. There is an Offset property on the Structfield. Use this to calculate the pointer value of a field. We can write a small test to verify that this is the right one.

type Testobj struct {field1 string}struct_ := &Testobj{}Field, _ := reflect.TypeOf(struct_).Elem().Fieldbyname("Field1")field1ptr := UIntPtr(unsafe.Pointer(struct_)) + Field.Offset*((*string)(unsafe.Pointer(field1ptr))) = "Hello"FMT.Println(struct_)

The printed message is &{hello}

Get Pointer to interface{}

If the corresponding struct is passed in as interface{}. You also need to get a pointer to the struct from interface{}

type Testobj struct {field1 string}struct_ := &Testobj{}Structinter := (Interface{})(struct_)//Emptyinterface is the header for a interface{} value.type Emptyinterface struct {Typ  *struct{}Word unsafe.Pointer}structptr := (*Emptyinterface)(unsafe.Pointer(&Structinter)).WordField, _ := reflect.TypeOf(Structinter).Elem().Fieldbyname("Field1")field1ptr := UIntPtr(structptr) + Field.Offset*((*string)(unsafe.Pointer(field1ptr))) = "Hello"FMT.Println(struct_)

Slice

The structure is done, and then the slice type is processed.

The corresponding code is in: Go/feature_reflect_array.go at Master Json-iterator/go GitHub

type sliceHeader struct {Data unsafe.PointerLen  intCap  int}

The secret of slice is to remove the pointer to the head of the array, and then the specific element, calculated by the offset.

Slice := []string{"Hello", "World"}type Sliceheader struct {Data unsafe.PointerLen  intCap  int}Header := (*Sliceheader)(unsafe.Pointer(&Slice))FMT.Println(Header.Len)ElementType := reflect.TypeOf(Slice).Elem()secondelementptr := UIntPtr(Header.Data) + ElementType.Size()*((*string)(unsafe.Pointer(secondelementptr))) = "!!!"FMT.Println(Slice)

Print out the content

2[hello!!!]

Map

There is no reflect for the Map type. How to get their content outside of ValueOf. So you can only honestly use the value of Golang to reflect the API.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.