人脑的容量有限,为了在有限的脑容量中高效的存储更多的知识,需要对知识进行归纳整理,变成自己的文章。但是并不是所有的知识都能够变成文章,出于篇幅、与其他知识点的关联等原因,很多知识当前还处于一种零散状态。
为了更有效的管理这些零散知识,现在将它们都存储在博客中的这个模块之中。当某些知识变成了一种常识或者许多知识积累了足够的信息量能够写一篇文章,则这些知识就会从这里删除。
计算机类一般性知识
Siphash算法
SipHash是由BLAKE算法的设计者Jean-Philippe Aumasson等人于2012年设计的,它是一类针对短消息设计的伪随机函数族,可用于消息认证,用途一般与MAC算法相似。
SipHash算法通过让输出随机化,能够有效减缓哈希洪水攻击凭借这一点,它逐渐成为Ruby、Python、Rust等语言默认的Hash表实现的一部分。
规则学习
规则学习是机器学习的一个子领域,专注于从数据中学习出能够描述数据分布所隐含的客观规律或领域概念的规则。这些规则通常以“如果…那么…”的形式表示,能够用于对未见示例进行判别
经典类型的规则学习算法与一般性的深度学习相比, 似乎并无明显优势. 唯一的优势是更加具备可解释性. 但如果是多个因子的复杂组合, 那么其可读性也未必比深度学习 有多高.
SIMD如何加速JSON反序列化
SIMD(单指令多数据)通过并行处理多个字符来加速JSON反序列化,尤其是在扫描结构字符(如引号、冒号)和批量处理数据时效果显著。以下是一个简化示例:
假设需要解析JSON字符串:"name":"John"
,目标是快速定位键值对的分隔符冒号 :
。
传统逐字符扫描
1 | const char* str = "\"name\":\"John\""; |
SIMD优化示例(伪代码)
使用SSE指令集(128位寄存器,一次处理16个字符):
1 |
|
关键优化点
- 批量比较:一次比较16个字符,而非逐个检查。
- 快速掩码生成:通过位操作(如
__builtin_ctz
)快速定位匹配位置。 - 减少分支预测失败:避免循环中的条件判断。
实际应用场景
• 结构字符扫描:快速定位{}
, []
, ,
, :
等符号。
• 转义字符处理:批量搜索反斜杠\
的位置。
• 数值解析:并行处理数字字符(如"value":1234
中的1234
)。
性能对比
• 传统方式:需循环N次(时间复杂度O(N))。
• SIMD方式:仅需N/16次循环(理论加速16倍,实际受内存对齐等因素影响)。
通过将重复性字符操作向量化,SIMD显著减少了JSON解析中耗时的扫描步骤。
SIMD加速JSON解析的实践与思考
JSON解析常被认为难以利用SIMD加速, 因为其包含大量分支跳转(处理转义字符、类型推断、括号匹配等)。但现代解析器通过架构分层设计, 在特定环节实现了3-5倍的SIMD加速。我们通过几个关键优化点来解析这个矛盾。
阶段分离策略
高效解析器的核心是将任务拆分为两个阶段:
1 | // 阶段1: SIMD预扫描 (向量化友好) |
第一阶段用SIMD批量处理结构化标记, 实测占整体耗时的35%-50%。第二阶段虽然存在分支, 但通过预先生成的位图减少了50%以上的冗余判断。
关键优化技术对比
优化手段 | 传统方案 (ns/op) | SIMD优化后 (ns/op) | 加速比 |
---|---|---|---|
引号匹配 | 82 | 19 | 4.3x |
数字解析 | 67 | 28 | 2.4x |
转义字符处理 | 113 | 105 | 1.1x |
整体解析 | 420 | 155 | 2.7x |
测试数据: 100KB嵌套JSON, Ice Lake平台
突破分支限制的实践
在必须保留分支的场景下, 通过掩码运算重构逻辑:
1 | // 传统分支写法 |
这种方法在解析10万级键值对时, 分支预测失败率从18%降至3.7%。
混合架构的价值
simdjson等领先解析器的设计启示:
- 分层处理: SIMD负责结构扫描, 标量代码处理业务逻辑
- 内存优化: 通过位图记录结构偏移, 避免二次扫描
- 并行试探: 对数值类型预转换, 失败时回退到稳健解析
1 | 解析流水线示例: |
取舍的艺术
SIMD在JSON解析中的实践证明了工程优化的典型特征: 在局部热点上集中火力。当某个子任务满足以下特征时, 就值得尝试SIMD加速:
- 数据处理量占比 >20%
- 可转换为位/掩码操作
- 能通过预计算减少后续工作
这种针对性优化使得现代解析器在保持通用性的同时, 性能逼近手动编写的二进制协议解析器, 为数据密集型应用提供了重要助力。
Protobuf相关知识
protobuf是一种将结构化数据序列化的机制, 可用于内部设备通信或存储. 与JSON格式相比, 基于protobuf协议的二进制文件体积更小, 解析速度更快.
protobuf简介
类型
类型 | 解释 |
---|---|
float, double | 浮点数 |
int32, int64, uint32, uint64 | 整数,但不适合编码较大的数字和负数 |
sint32, sint64 | 针对负数进行优化的整数类型 |
fixed32, fixed64, sfixed32, sfixed64 | 更适合大数字的有符号数或无符号数 |
bool | 布尔值 |
string | 任意的UTF-8字符串 |
byte | 任意的字节 |
protobuf对数字存储进行了优化,一个数字越小则存储长度越短。由于计算机使用补码表示负数,因此通常情况下负数将使用多个字节表示。为了优化这种情况,sint类型使用交叉的方式表示,绝对值较小的负数依然可以获得较短的存储长度。
protobuf命名冲突解决方案
对于PB的namespace, 规范要求每个PB都是全局唯一的. 如果设计不合理就会导致PB名称冲突, 对于高版本的依赖库, Go语言在启动时会直接painc, 导致系统无法启动.
对于上述问题, 可以通过降级依赖版本临时解决:
1 | replace ( |
有趣的项目推荐
Github使用
免费开发环境
每月可免费使用120核心小时的服务器资源. 停止运行后, 不计算核心小时资源, 仅计算存储资源.
默认启用2核心服务器, 可使用60小时, 平均每天可使用2小时. 30min无操作自动关闭, 几乎等于无限制使用.
Calibre优化
书籍样式修改
对于EPUB格式的数据, 实际上就是压缩格式的HTML代码, 因此可以使用HTML的技术进行修改, 例如调整文字行间距, 可使用属性
1 | <p style="line-height:1.5;"> |
将行间距调整为1.5倍
机器学习
大模型提示词
- 赛博人格分裂,(启动人格分裂讨论模式+问题)
- 阴阳怪气模式,(问题+笑死)毒舌属性
- 触发预判模式,假设性问题(如果,,,会不会,,,)
- 预言家模式,预判未来(如果,,,会发生什么)
- 灵魂拷问模式,(①启动杠精模式②先写方案,再模拟杠精从*个角度狂喷,最后给出V2版方案),
- 玄学编程(,,,带点蝉意)
- 驯服转业话痨,(说人话!)
- 人设粘贴术,
- 启动老板思维(如果你是,,,你会怎么骂这个方案)
- 过滤废话,(问题,+删掉所有正确的废话,只留能落地的建议)
高性能服务设计原则
高并发原则
无状态:
拆分:
服务化
消息队列
缓存:
高可用原则
降级:
限流
切流量
可回滚
最后更新: 2025年04月20日 21:28
版权声明:本文为原创文章,转载请注明出处