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

2024-01-16 00:13:14 +08:00
huahsiung  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 使用性能差别有多大

4780 次点击
所在节点   程序员  程序员
54 条回复
zyxk
zyxk
2024-01-16 00:23:38 +08:00
我也想知道,等看结果
nagisaushio
nagisaushio
2024-01-16 00:26:38 +08:00
楼主可以贴下测试代码吗?直觉上 redis 应该会慢很多,毕竟隔了个 tcp 传输
yhtbiy
yhtbiy
2024-01-16 00:39:55 +08:00
这不是性能的问题吧,Redis 数据是可以持久的,你 go 内存里的重启了数据就都没了
dobelee
dobelee
2024-01-16 00:49:58 +08:00
1. 你的例子过于简单,实际业务大多存储结构体,这就涉及编解码和序列化的 CPU 内存消耗。本地缓存无需。
2. 你连接的是本地 redis ,连接耗时忽略,也不存在高峰期的网络波动。没有任何测试意义。
doraemonki
doraemonki
2024-01-16 02:01:59 +08:00
应该是内置的快,没有持久化需求直接用内置的 map
kneo
kneo
2024-01-16 02:09:45 +08:00
瞎猜一个一百倍。你可以自己测一下。
Trim21
Trim21
2024-01-16 02:13:09 +08:00
内置大概的微秒级,Redis 毫秒级
jinliming2
jinliming2
2024-01-16 03:33:11 +08:00
虽然不知道 go 原生 map 和用 Redis 的性能差异,即便是 Redis 更快,为什么只用 localhost:port 的 TCP 连接本地回环的方式来访问 Redis 呢?在 Linux 上使用 unix domain sockets 的方式不是会更快吗?根据 Redis 官方文档上的数据,unix sockets 的吞吐量能提高 50%。
而不支持 unix sockets 的 windows 貌似用 Redis 本身就有性能瓶颈,感觉还不如直接用 go 原生 map 。
bianhui
bianhui
2024-01-16 08:07:11 +08:00
得看,看 key 的数量,结构,数据类型,操作方法。稍微读一下两个源码就知道
wdmx007
wdmx007
2024-01-16 08:07:20 +08:00
不是做二级缓存的话,在性能足够的情况下,用 redis 使应用无状态,有利于后续横向扩展
sxfscool
sxfscool
2024-01-16 08:43:53 +08:00
场景不一样,没什么可比性
sujin190
sujin190
2024-01-16 08:44:39 +08:00
微秒级和纳秒级,如果一个语言标准库 hash 表才有读 redis 的速度,那这语言太废了,没有 4 个数量级的差距说不定都是你用的有问题
iseki
iseki
2024-01-16 08:56:18 +08:00
再注意下,数据序列化/反序列化
fzdwx
fzdwx
2024-01-16 08:57:20 +08:00
你看的是什么项目?
Nazz
Nazz
2024-01-16 09:03:56 +08:00
大概 100ns/op 和 1ms/op 的差异
bthulu
bthulu
2024-01-16 09:14:47 +08:00
测试代码
```
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
2024-01-16 09:17:49 +08:00
更新重复一万次测试结果
```
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
2024-01-16 09:20:57 +08:00
一个内存读,可能还用 cpu 缓存,一个跨网络读
alsas
2024-01-16 09:27:44 +08:00
肯定是本地快啊 没经过网络
zzhaolei
2024-01-16 09:29:01 +08:00
这个测试没意义啊,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