go 语言直接使用 map 和连接 Redis 后使用 Map 性能差别有多大

163 天前
 huahsiung

go 语言直接使用 map 很方便

map1 := make(map[string]int)
key1 := map1["str1"]

但是发现有些 go 项目源码偏向使用 Redis 等第三方的 map.

import (
    github.com/go-redis/redis"
)
 client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379", 
        Password: "",               
        DB:       0,                
    })
client.Ping()
client.HSet("myhash", "key1", "value1")
value1, err := client.HGet("myhash", "")

然后看到项目的 map 并不是并发使用的,数据量也不是特别大。(有些并没有持久需求的也在使用 redis )

go map 和 redis map 都是内存使用的,而且速度也很快。但是很多需要查找 hash 关系表的项目,偏向使用如 redis map 等第三方表。

我粗略测试了一下,没看出什么区别(可能我测试数据较小)。如果排除 go map 不能并发读写外与 Redis Map 使用性能差别有多大

4300 次点击
所在节点    程序员
54 条回复
zyxk
163 天前
我也想知道,等看结果
nagisaushio
163 天前
楼主可以贴下测试代码吗?直觉上 redis 应该会慢很多,毕竟隔了个 tcp 传输
yhtbiy
163 天前
这不是性能的问题吧,Redis 数据是可以持久的,你 go 内存里的重启了数据就都没了
dobelee
162 天前
1. 你的例子过于简单,实际业务大多存储结构体,这就涉及编解码和序列化的 CPU 内存消耗。本地缓存无需。
2. 你连接的是本地 redis ,连接耗时忽略,也不存在高峰期的网络波动。没有任何测试意义。
doraemonki
162 天前
应该是内置的快,没有持久化需求直接用内置的 map
kneo
162 天前
瞎猜一个一百倍。你可以自己测一下。
Trim21
162 天前
内置大概的微秒级,Redis 毫秒级
jinliming2
162 天前
虽然不知道 go 原生 map 和用 Redis 的性能差异,即便是 Redis 更快,为什么只用 localhost:port 的 TCP 连接本地回环的方式来访问 Redis 呢?在 Linux 上使用 unix domain sockets 的方式不是会更快吗?根据 Redis 官方文档上的数据,unix sockets 的吞吐量能提高 50%。
而不支持 unix sockets 的 windows 貌似用 Redis 本身就有性能瓶颈,感觉还不如直接用 go 原生 map 。
bianhui
162 天前
得看,看 key 的数量,结构,数据类型,操作方法。稍微读一下两个源码就知道
wdmx007
162 天前
不是做二级缓存的话,在性能足够的情况下,用 redis 使应用无状态,有利于后续横向扩展
sxfscool
162 天前
场景不一样,没什么可比性
sujin190
162 天前
微秒级和纳秒级,如果一个语言标准库 hash 表才有读 redis 的速度,那这语言太废了,没有 4 个数量级的差距说不定都是你用的有问题
iseki
162 天前
再注意下,数据序列化/反序列化
fzdwx
162 天前
你看的是什么项目?
Nazz
162 天前
大概 100ns/op 和 1ms/op 的差异
bthulu
162 天前
测试代码
```
Dictionary<int, int> dict = new() { { 1, 1 } };
Stopwatch stopwatch = Stopwatch.StartNew();
int i = dict[1];
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
using ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase database = redis.GetDatabase();
database.HashSet("key", 1, 1);
stopwatch = Stopwatch.StartNew();
RedisValue redisValue = database.HashGet("key", 1);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
```

测试结果:
```
746
18209
```

一句话: 内存 map 快 25 倍
bthulu
162 天前
更新重复一万次测试结果
```
Dictionary<int, int> dict = new() { { 1, 1 } };
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
int j = dict[1];
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
using ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase database = redis.GetDatabase();
database.HashSet("key", 1, 1);
stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
RedisValue redisValue = database.HashGet("key", 1);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
```
输出
```
1228
9577919
```
一句话: 内存 map 快 7800 倍
acerphoenix
162 天前
一个内存读,可能还用 cpu 缓存,一个跨网络读
alsas
162 天前
肯定是本地快啊 没经过网络
zzhaolei
162 天前
这个测试没意义啊,redis 能持久存储,map 不行,redis 也有一些回收和超时策略,这两个都不是一个东西,使用场景不一样

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1008921

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX