本文由字节跳动技术团队杨晨曦分享,即时通讯网有修订和改动。
cover-opti.jpg (29.04 KB, 下载次数: 563)
下载附件 保存到相册
12 个月前 上传
1.jpg (38.75 KB, 下载次数: 552)
2.png (31.33 KB, 下载次数: 531)
3.png (17.58 KB, 下载次数: 533)
// 接口 service SupService { SearchDepartmentByKeywordResponse SearchDepartmentByKeyword( 1: SearchDepartmentByKeywordRequest request) } // 请求 struct SearchDepartmentByKeywordRequest { 1: optional string Keyword 2: optional i32 Limit 3: optional i32 Offset } // 假设request的payload如下: { Keyword: "lark", Limit: 50, Offset: nil, }
4.png (10.92 KB, 下载次数: 532)
/* 接口名长度 */ 0 0 0 25 /* 接口名 */ 83 101 97 114 99 104 68 101 112 97 114 116 109 101 110 116 66 121 75 101 121 119 111 114 100 /* 消息类型 */ 1 /* 消息序号 */ 0 0 0 1 /* keyword 字段类型 */ 11 /* keyword 字段ID*/ 0 1 /* keyword len */ 0 0 0 4 /* keyword value */ 108 97 114 107 /* limit 字段类型 */ 8 /* limit 字段ID*/ 0 2 /* limit value */ 0 0 0 50 /* 字段终止符 */ 0
5.png (11.48 KB, 下载次数: 547)
6.png (19.48 KB, 下载次数: 524)
解决的问题:定长存储的整数类型绝对值较小时空间浪费大。
00000000 00000000 00000000 00000111
解决思路:将整数类型由定长存储转为变长存储(能用 1 个字节存下就坚决不用 2 个字节)
binary编码: 00000000 00000000 00000011 10111011 切分: 0000 0000000 0000000 0000111 0111011 compact编码: 00000111 10111011
解决的问题:绝对值较小的负数经过 varint 编码后空间开销较大 举个 🌰,i32 类型的负数(-11)
原码: 10000000 00000000 00000000 00001011 反码: 11111111 11111111 11111111 11110100 补码: 11111111 11111111 11111111 11110101 varint编码: 00001111 11111111 11111111 11111111 11110101
解决思路:负数转正数,从而把前导 1 转成前导 0,便于 varint 压缩
// 算法公式 32位: (n << 1) ^ (n >> 31) 64位: (n << 1) ^ (n >> 63) /* * 算法步骤: * 1. 不分正负:符号位后置,数值位前移 * 2. 对于负数:符号位不变,数值位取反 */ // 示例 负数(-11) 补码: 11111111 11111111 11111111 11110101 符号位后置,数值位前移: 11111111 11111111 11111111 11101011 符号位不变,数值位取反(21): 00000000 00000000 00000000 00010101 正数(11) 补码: 00000000 00000000 00000000 00010101 符号位后置,数值位前移(22): 00000000 00000000 00000000 00101010
编码前 编码后 0 0 -1 1 1 2 -2 3 2 4
/* bool、i8、i16、i32、i64、double、string */ "编号": { "类型": "值" } // 示例 "1": { "str": "keyword" } /* struct */ "编号": { "rec": { "成员编号": { "成员类型": "成员值" }, ... } } // 示例 "1": { "rec": { "1": { "i32": 50 } } } /* map */ "编号": { "map": [ "键类型", "值类型", 元素个数, "键1", "值1", ... "键n", "值n" ] } // 示例 "6": { "map": [ "i64", "str", 1, 666, "mapValue" ] } /* List */ "编号": { "set/lst": [ "值类型", 元素个数, "ele1", "ele2", "elen" ] } // 示例 "2": { "lst": [ "str", 2, "lark","keyword"] }
7.png (67.63 KB, 下载次数: 561)
00000000 00000000 00000001 01111010 00101010 00111011 00000001 00111110
8.png (26.8 KB, 下载次数: 541)
9.png (29.39 KB, 下载次数: 527)
10.png (23.92 KB, 下载次数: 560)
11.png (11.54 KB, 下载次数: 550)
来源:即时通讯网 - 即时通讯开发者社区!
轻量级开源移动端即时通讯框架。
快速入门 / 性能 / 指南 / 提问
轻量级Web端即时通讯框架。
详细介绍 / 精编源码 / 手册教程
移动端实时音视频框架。
详细介绍 / 性能测试 / 安装体验
基于MobileIMSDK的移动IM系统。
详细介绍 / 产品截图 / 安装体验
一套产品级Web端IM系统。
详细介绍 / 产品截图 / 演示视频
引用此评论
精华主题数超过100个。
连续任职达2年以上的合格正式版主
为论区做出突出贡献的开发者、版主等。
Copyright © 2014-2024 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.125981 second(s), 41 queries , Gzip On.