golang deepcopy_mongodb主从复制原理
2023-06-13 09:15:01 时间
大家好,又见面了,我是你们的朋友全栈君。
Go语言中所有赋值操作都是值传递,如果结构中不含指针,则直接赋值就是深度拷贝;如果结构中含有指针(包括自定义指针,以及切片,map等使用了指针的内置类型),则数据源和拷贝之间对应指针会共同指向同一块内存,这时深度拷贝需要特别处理。目前,有三种方法,一是用gob序列化成字节序列再反序列化生成克隆对象;二是先转换成json字节序列,再解析字节序列生成克隆对象;三是针对具体情况,定制化拷贝。前两种方法虽然比较通用但是因为使用了reflex反射,性能比定制化拷贝要低出2个数量级,所以在性能要求较高的情况下应该尽量避免使用前两者。
结论数据:
执行一次的时间
gob time:454µs json time:170µs custom time:2µs
测试代码如下:
package main
import (
"bytes"
"encoding/gob"
"encoding/json"
"fmt"
"time"
)
type AuthorInfo struct {
Name string `json:name`
Age int `json:age`
Country *int `json:country`
}
type Book struct {
Title string `json:title`
Author AuthorInfo `json:author`
Year int `json:year`
Category []string `json:category`
Price map[string]string `json:price`
}
func DeepCopyByGob(dst, src interface{}) error {
var buffer bytes.Buffer
if err := gob.NewEncoder(&buffer).Encode(src); err != nil {
return err
}
return gob.NewDecoder(&buffer).Decode(dst)
}
func DeepCopyByJson(src []Book) (*[]Book, error) {
var dst = new([]Book)
b, err := json.Marshal(src)
if err != nil {
return nil, err
}
err = json.Unmarshal(b, dst)
return dst, err
}
func DeepCopyByCustom(src []Book) []Book {
dst := make([]Book, len(src))
for i, book := range src {
tmpbook := Book{}
tmpbook.Title = book.Title
tmpbook.Year = book.Year
tmpbook.Author = AuthorInfo{}
tmpbook.Author.Name = book.Author.Name
tmpbook.Author.Age = book.Author.Age
tmpbook.Author.Country = new(int)
*tmpbook.Author.Country = *book.Author.Country
tmpbook.Category = make([]string, len(book.Category))
for index, category := range book.Category {
tmpbook.Category[index] = category
}
tmpbook.Price = make(map[string]string)
for k, v := range book.Price {
tmpbook.Price[k] = v
}
dst[i] = tmpbook
}
return dst
}
func check(err error){
if err != nil{
panic(err)
}
}
func print(name string, books []Book){
for index,book := range books{
fmt.Printf("%s[%d]=%v country=%d\n", name, index, book, *book.Author.Country)
}
}
func main() {
//初始化源Book切片
books := make([]Book, 1)
country := 1156
author := AuthorInfo{"David", 38, &country}
price := make(map[string]string)
price["Europe"] = "$56"
books[0] = Book{"Tutorial", author, 2020, []string{"math", "art"}, price}
print("books",books)
var err error
var start time.Time
//Gob拷贝
start = time.Now()
booksCpy := make([]Book, 1)
err = DeepCopyByGob(&booksCpy, books)
fmt.Printf("\ngob time:%v\n", time.Now().Sub(start))
check(err)
*booksCpy[0].Author.Country = 1134
booksCpy[0].Category[0] = "literature"
booksCpy[0].Price["America"] = "$250"
print("booksCpy",booksCpy)
print("books",books)
//JSON拷贝
start = time.Now()
booksCpy2, err_json := DeepCopyByJson(books)
fmt.Printf("\njson time:%v\n", time.Now().Sub(start))
check(err_json)
*(*booksCpy2)[0].Author.Country = 1135
(*booksCpy2)[0].Category[0] = "science"
(*booksCpy2)[0].Price["Canada"] = "$150"
print("(*booksCpy2)",*booksCpy2)
print("books",books)
//定制拷贝
start = time.Now()
booksCpy3 := DeepCopyByCustom(books)
fmt.Printf("\ncustom time:%v\n", time.Now().Sub(start))
*booksCpy3[0].Author.Country = 1136
booksCpy3[0].Category[0] = "geometry"
booksCpy3[0].Price["Africa"] = "$34"
print("booksCpy3",booksCpy3)
print("books",books)
}
运行输出:
books[0]={Tutorial {David 38 0xc000016178} 2020 [math art] map[Europe:$56]} country=1156
gob time:454.117µs
booksCpy[0]={Tutorial {David 38 0xc0000165d8} 2020 [literature art] map[America:$250 Europe:$56]} country=1134
books[0]={Tutorial {David 38 0xc000016178} 2020 [math art] map[Europe:$56]} country=1156
json time:170.338µs
(*booksCpy2)[0]={Tutorial {David 38 0xc000016878} 2020 [science art] map[Canada:$150 Europe:$56]} country=1135
books[0]={Tutorial {David 38 0xc000016178} 2020 [math art] map[Europe:$56]} country=1156
custom time:2.165µs
booksCpy3[0]={Tutorial {David 38 0xc0000168c8} 2020 [geometry art] map[Africa:$34 Europe:$56]} country=1136
books[0]={Tutorial {David 38 0xc000016178} 2020 [math art] map[Europe:$56]} country=1156
相关文章:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186667.html原文链接:https://javaforall.cn
相关文章
- Node.js学习笔记(四)——NodeJS访问MongoDB与MySQL数据库
- 高可用mongodb集群(分片+副本):规划及部署
- mongodb 数据库 linux系统下集群搭建过程
- mongoDB数据库备份恢复 之 mongodb 4.2.8备份恢复与导出导入
- MongoDB特点与体系结构等简介
- MongoDB安装与使用:一步一步学会实践(mongodb安装与使用)
- MongoDB操作指南(mongodb操作)
- 初学者必读:MongoDB入门指南(怎样使用mongoDB)
- MongoDB技术:存储文件的新方式(mongodb存文件)
- MongoDB: 预防SQL注入攻击的必要手段(mongodb注入)
- MongoDB连接简单实现你的数据梦想(mongodb连接)
- MongoDB 数据库设计:从基础原理到优化实践(mongodb数据库设计)
- MongoDB字段排序:轻松一步到位(mongodb字段排序)
- 主键MongoDB自增主键技术实现原理(mongodb自增)
- 数据库MongoDB:如何快速清空数据库(mongodb清空)
- MongoDB 清空数据库的操作步骤(mongodb清库)
- 深入浅出:MongoDB的原理及实现.(mongodb实现原理)
- MongoDB索引:提高性能的关键步骤(mongodb索引)
- Mongodb轻松创建新数据库,提高数据存储效率(mongodb新建数据库)
- MongoDB实现图片上传功能(mongodb上传图片)
- 查询MongoDB精准转义查询:力求完美结果(mongodb转义)
- MongoDB数据库压缩技术研究(mongodb压缩)
- 如何在MongoDB中恢复误删除的数据(mongodb恢复数据)
- 如何设置 MongoDB 的环境变量?(mongodb环境变量)
- 使用MongoDB的in操作符查询特定条件下的数据(mongodbin)
- Mastering MongoDB: Essential Tips and Tricks for Efficient Database Operations(mongodb数据库操作)
- 使用 MongoDB 登陆数据库,简单高效(mongodb登陆数据库)
- 「了解MongoDB索引查看」(mongodb索引查看)
- 深入理解MongoDB索引原理(mongodb 索引原理)
- 安装MongoDB,接入PHP开发新篇章(php安装mongodb)
- 及优缺点MongoDB分片技术:原理与优缺点分析(mongodb分片原理)
- MongoDB查询优化:让你的数据分析更有效(mongodb 查询分析)