Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ResultMarshal-range #99

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Mr-Ao-Dragon
Copy link

No description provided.

@lutaoact
Copy link
Collaborator

有两个问题反馈下:

  • 需要补充下 UT
  • 当前只处理了单版本的情况,是否方便把多版本也支持

@Mr-Ao-Dragon
Copy link
Author

Mr-Ao-Dragon commented Mar 28, 2024

有两个问题反馈下:

  • 需要补充下 UT
  • 当前只处理了单版本的情况,是否方便把多版本也支持

之后再提一个pr以便支持,需要指出的是,这会带来额外的用户编写复杂度

@lutaoact
Copy link
Collaborator

我做了 benchmark,以下是示例代码,Marshal 是你的原始函数,Marshal2 是我直接 for 循环,Marshal3 是我改成指针接收者调用函数,Marshal3 是最快的。

package tablestore

import (
	"fmt"
	"sync"
	"testing"
)

func marshal(pks []*PrimaryKeyColumn, cols []*AttributeColumn) (primaryKeys map[string]interface{}, rows map[string]interface{}) {
	primaryKeys = make(map[string]interface{})
	for _, pk := range pks {
		primaryKeys[pk.ColumnName] = pk.Value
	}

	rows = make(map[string]interface{})
	for _, col := range cols {
		rows[col.ColumnName] = col.Value
	}
	return
}

func (response Row) Marshal() (primaryKeys map[string]interface{}, rows map[string]interface{}) {
	return marshal(response.PrimaryKey.PrimaryKeys, response.Columns)
}

type SingleRow struct {
	PrimaryKey map[string]interface{} // 主键
	Row        map[string]interface{} // 行数据
}

type Rows struct {
	mu   sync.Mutex
	Data RowData
}

type RowData map[int32]*SingleRow

func (response GetRangeResponse) Marshal() (*RowData, error) {
	rows := &Rows{Data: make(map[int32]*SingleRow)}
	var wg sync.WaitGroup

	for index, data := range response.Rows { // 假设response.Rows是Row类型的切片,且Row实现了Marshal方法
		wg.Add(1)
		go func(index int32, data *Row) {
			defer wg.Done()

			singleRow := new(SingleRow)
			singleRow.PrimaryKey, singleRow.Row = data.Marshal() // 假设Row类型有Marshal方法可以直接使用

			// 在写入之前锁定mutex
			rows.mu.Lock()
			rows.Data[index] = singleRow
			rows.mu.Unlock()
		}(int32(index), data)
	}

	wg.Wait()

	// 返回指向Rows.Data的指针,满足函数签名的要求
	return &rows.Data, nil
}

func (response GetRangeResponse) Marshal2() (*RowData, error) {
	rowData := make(RowData)

	for index, data := range response.Rows {
		pk, row := data.Marshal()
		rowData[int32(index)] = &SingleRow{PrimaryKey: pk, Row: row}
	}

	return &rowData, nil
}

func (response *GetRangeResponse) Marshal3() (*RowData, error) {
	rowData := make(RowData)

	for index, data := range response.Rows {
		pk, row := data.Marshal()
		rowData[int32(index)] = &SingleRow{PrimaryKey: pk, Row: row}
	}

	return &rowData, nil
}

type PrimaryKeyColumn struct {
	ColumnName string
	Value      interface{}
}

type AttributeColumn struct {
	ColumnName string
	Value      interface{}
}

type PrimaryKey struct {
	PrimaryKeys []*PrimaryKeyColumn
}

type Row struct {
	PrimaryKey *PrimaryKey
	Columns    []*AttributeColumn
}

type GetRangeResponse struct {
	Rows []*Row
}

var response GetRangeResponse
var responsePtr *GetRangeResponse

func init() {
	count := 5000
	response = GetRangeResponse{
		Rows: make([]*Row, count),
	}

	for i := 0; i < count; i++ {
		response.Rows[i] = &Row{
			PrimaryKey: &PrimaryKey{
				PrimaryKeys: []*PrimaryKeyColumn{
					&PrimaryKeyColumn{
						ColumnName: fmt.Sprintf("%d", i),
						Value:      i,
					},
				},
			},
			Columns: []*AttributeColumn{
				&AttributeColumn{
					ColumnName: fmt.Sprintf("%d", i),
					Value:      i,
				},
			},
		}
	}

	responsePtr = &response
}

func BenchmarkMarshal(b *testing.B) {
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		response.Marshal()
	}

	b.StopTimer()
}

func BenchmarkMarshal2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		response.Marshal2()
	}
}

func BenchmarkMarshal3(b *testing.B) {
	for i := 0; i < b.N; i++ {
		responsePtr.Marshal3()
	}
}

@Mr-Ao-Dragon Mr-Ao-Dragon marked this pull request as ready for review March 29, 2024 15:36
@Mr-Ao-Dragon
Copy link
Author

Mr-Ao-Dragon commented Mar 29, 2024

我做了 benchmark,以下是示例代码,Marshal 是你的原始函数,Marshal2 是我直接 for 循环,Marshal3 是我改成指针接收者调用函数,Marshal3 是最快的。

好的,我改成指针接收器,如果可以的话我希望您可以尝试更大的样本,考虑到表格存储的应用场景,所以我使用了无限制并发+互斥锁来并发 apped

Signed-off-by: 敖律风 <x123456789fy@outlook.com>
@Mr-Ao-Dragon
Copy link
Author

@lutaoact 请告诉我您的审查结果

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants