优化Cereal宏 一行声明序列化函数

Cereal序列化库中宏递归展开的优化方案及技术解析

未优化:参考nlohmann json设计Cereal宏 一行声明序列化函数

宏实现

#include <cereal/cereal.hpp>// 强制二次展开
#define CEREAL_EXPAND( x ) x// 获取宏参数的数量,对应的CEREAL_PASTEn宏NAME
#define CEREAL_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15,	\_16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28,	\_29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41,	\_42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54,	\_55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME// 参数拼接宏(支持1-64个参数)
#define CEREAL_PASTE(...) CEREAL_EXPAND(CEREAL_GET_MACRO(__VA_ARGS__, \CEREAL_PASTE64, CEREAL_PASTE63, CEREAL_PASTE62, CEREAL_PASTE61, \CEREAL_PASTE60, CEREAL_PASTE59, CEREAL_PASTE58, CEREAL_PASTE57, \CEREAL_PASTE56, CEREAL_PASTE55, CEREAL_PASTE54, CEREAL_PASTE53, \CEREAL_PASTE52, CEREAL_PASTE51, CEREAL_PASTE50, CEREAL_PASTE49, \CEREAL_PASTE48, CEREAL_PASTE47, CEREAL_PASTE46, CEREAL_PASTE45, \CEREAL_PASTE44, CEREAL_PASTE43, CEREAL_PASTE42, CEREAL_PASTE41, \CEREAL_PASTE40, CEREAL_PASTE39, CEREAL_PASTE38, CEREAL_PASTE37, \CEREAL_PASTE36, CEREAL_PASTE35, CEREAL_PASTE34, CEREAL_PASTE33, \CEREAL_PASTE32, CEREAL_PASTE31, CEREAL_PASTE30, CEREAL_PASTE29, \CEREAL_PASTE28, CEREAL_PASTE27, CEREAL_PASTE26, CEREAL_PASTE25, \CEREAL_PASTE24, CEREAL_PASTE23, CEREAL_PASTE22, CEREAL_PASTE21, \CEREAL_PASTE20, CEREAL_PASTE19, CEREAL_PASTE18, CEREAL_PASTE17, \CEREAL_PASTE16, CEREAL_PASTE15, CEREAL_PASTE14, CEREAL_PASTE13, \CEREAL_PASTE12, CEREAL_PASTE11, CEREAL_PASTE10, CEREAL_PASTE9,  \CEREAL_PASTE8,  CEREAL_PASTE7,  CEREAL_PASTE6,  CEREAL_PASTE5,  \CEREAL_PASTE4,  CEREAL_PASTE3,  CEREAL_PASTE2,  CEREAL_PASTE1)(__VA_ARGS__))// 定义PASTE宏(1-64个参数)
#define CEREAL_PASTE2(func, param) func(param)
#define CEREAL_PASTE3(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
#define CEREAL_PASTE4(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE3(func, __VA_ARGS__))
#define CEREAL_PASTE5(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE4(func, __VA_ARGS__))
#define CEREAL_PASTE6(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE5(func, __VA_ARGS__))
#define CEREAL_PASTE7(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE6(func, __VA_ARGS__))
#define CEREAL_PASTE8(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE7(func, __VA_ARGS__))
#define CEREAL_PASTE9(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE8(func, __VA_ARGS__))
#define CEREAL_PASTE10(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE9(func, __VA_ARGS__))
#define CEREAL_PASTE11(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE10(func, __VA_ARGS__))
#define CEREAL_PASTE12(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE11(func, __VA_ARGS__))
#define CEREAL_PASTE13(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE12(func, __VA_ARGS__))
#define CEREAL_PASTE14(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE13(func, __VA_ARGS__))
#define CEREAL_PASTE15(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE14(func, __VA_ARGS__))
#define CEREAL_PASTE16(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE15(func, __VA_ARGS__))
#define CEREAL_PASTE17(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE16(func, __VA_ARGS__))
#define CEREAL_PASTE18(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE17(func, __VA_ARGS__))
#define CEREAL_PASTE19(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE18(func, __VA_ARGS__))
#define CEREAL_PASTE20(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE19(func, __VA_ARGS__))
#define CEREAL_PASTE21(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE20(func, __VA_ARGS__))
#define CEREAL_PASTE22(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE21(func, __VA_ARGS__))
#define CEREAL_PASTE23(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE22(func, __VA_ARGS__))
#define CEREAL_PASTE24(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE23(func, __VA_ARGS__))
#define CEREAL_PASTE25(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE24(func, __VA_ARGS__))
#define CEREAL_PASTE26(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE25(func, __VA_ARGS__))
#define CEREAL_PASTE27(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE26(func, __VA_ARGS__))
#define CEREAL_PASTE28(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE27(func, __VA_ARGS__))
#define CEREAL_PASTE29(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE28(func, __VA_ARGS__))
#define CEREAL_PASTE30(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE29(func, __VA_ARGS__))
#define CEREAL_PASTE31(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE30(func, __VA_ARGS__))
#define CEREAL_PASTE32(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE31(func, __VA_ARGS__))
#define CEREAL_PASTE33(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE32(func, __VA_ARGS__))
#define CEREAL_PASTE34(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE33(func, __VA_ARGS__))
#define CEREAL_PASTE35(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE34(func, __VA_ARGS__))
#define CEREAL_PASTE36(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE35(func, __VA_ARGS__))
#define CEREAL_PASTE37(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE36(func, __VA_ARGS__))
#define CEREAL_PASTE38(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE37(func, __VA_ARGS__))
#define CEREAL_PASTE39(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE38(func, __VA_ARGS__))
#define CEREAL_PASTE40(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE39(func, __VA_ARGS__))
#define CEREAL_PASTE41(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE40(func, __VA_ARGS__))
#define CEREAL_PASTE42(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE41(func, __VA_ARGS__))
#define CEREAL_PASTE43(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE42(func, __VA_ARGS__))
#define CEREAL_PASTE44(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE43(func, __VA_ARGS__))
#define CEREAL_PASTE45(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE44(func, __VA_ARGS__))
#define CEREAL_PASTE46(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE45(func, __VA_ARGS__))
#define CEREAL_PASTE47(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE46(func, __VA_ARGS__))
#define CEREAL_PASTE48(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE47(func, __VA_ARGS__))
#define CEREAL_PASTE49(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE48(func, __VA_ARGS__))
#define CEREAL_PASTE50(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE49(func, __VA_ARGS__))
#define CEREAL_PASTE51(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE50(func, __VA_ARGS__))
#define CEREAL_PASTE52(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE51(func, __VA_ARGS__))
#define CEREAL_PASTE53(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE52(func, __VA_ARGS__))
#define CEREAL_PASTE54(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE53(func, __VA_ARGS__))
#define CEREAL_PASTE55(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE54(func, __VA_ARGS__))
#define CEREAL_PASTE56(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE55(func, __VA_ARGS__))
#define CEREAL_PASTE57(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE56(func, __VA_ARGS__))
#define CEREAL_PASTE58(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE57(func, __VA_ARGS__))
#define CEREAL_PASTE59(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE58(func, __VA_ARGS__))
#define CEREAL_PASTE60(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE59(func, __VA_ARGS__))
#define CEREAL_PASTE61(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE60(func, __VA_ARGS__))
#define CEREAL_PASTE62(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE61(func, __VA_ARGS__))
#define CEREAL_PASTE63(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE62(func, __VA_ARGS__))
#define CEREAL_PASTE64(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE63(func, __VA_ARGS__))// 成员处理宏
#define CEREAL_MEMBER_NVP_NON_INTRUSIVE(member) ::cereal::make_nvp(#member, t.member)// 主序列化宏:非侵入的
#define CEREAL_SERIALIZE_NON_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar, const Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}\
template <class Archive> \
void serialize(Archive& ar, Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}// 主序列化宏:侵入的
#define CEREAL_SERIALIZE_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar) { \ar( CEREAL_PASTE(CEREAL_NVP, __VA_ARGS__) ); \
}

技术解析:

🔧 优化后的宏定义

#define CEREAL_EXPAND(x) x  // 强制二次展开
#define CEREAL_PASTE2(func, x) func(x)
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
#define CEREAL_PASTE4(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE3(func, __VA_ARGS__))
#define CEREAL_PASTE5(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE4(func, __VA_ARGS__))

🔁 方案1:CEREAL_EXPAND的作用

1. 强制二次展开
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
  • 展开流程(以CEREAL_PASTE3(F, a, b, c)为例):

    1. 首次展开:F(a), CEREAL_EXPAND(CEREAL_PASTE2(F, b, c))
    2. CEREAL_EXPAND强制展开其参数:CEREAL_PASTE2(F, b, c) → F(b), F(c)
    3. 最终结果:F(a), F(b), F(c)
2. 必要性分析
  • CEREAL_EXPAND
    CEREAL_PASTE2(func, __VA_ARGS__)作为文本保留,后续不再展开。

  • CEREAL_EXPAND
    通过CEREAL_EXPAND包裹,预处理器会立即展开内层宏,确保递归链继续。

⚠️ 方案2缺陷(无CEREAL_EXPAND

1.没有二次展开
// 原方案(错误示例)
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_PASTE2(func, __VA_ARGS__)
  • 问题:当调用CEREAL_PASTE3(func, x, y, z)时:
    • 首次展开:func(x), CEREAL_PASTE2(func, y, z)
    • 由于预处理器不会自动展开嵌套宏CEREAL_PASTE2(func, y, z)被视为整体而非宏调用。
    • 结果:func(x), CEREAL_PASTE2(func, y, z) → 后续参数未展开,导致编译错误。
2. 关键机制:宏展开的惰性
  • 预处理器展开规则:
    • 当宏参数包含其他宏(如__VA_ARGS__中的CEREAL_PASTE2)时,不会立即展开,而是作为文本保留。
    • 只有当前层宏完全展开后,才会处理嵌套宏(若未被###修饰)。

📊 技术方案对比

场景方案1(含CEREAL_EXPAND方案2(无CEREAL_EXPAND
CEREAL_PASTE3(F, a, b)F(a), F(b)F(a), CEREAL_PASTE2(F, b)
CEREAL_PASTE4(F, a,b,c)F(a), F(b), F(c)F(a), CEREAL_PASTE3(F, b,c)
嵌套宏展开递归展开至最内层停止于第一层

🧠 技术原理:预处理器展开规则

  1. 递归展开条件:
    • 宏必须完全独立(未被#/##修饰)。
    • 每轮扫描只展开当前层的宏标识符,嵌套宏需等待外层展开完成。
  2. CEREAL_EXPAND的突破性
    • 通过中间层宏(CEREAL_EXPAND)隔离,使内层宏(如CEREAL_PASTE2)满足“独立标识符”条件,触发其展开。

💻 实际应用示例

1. 序列化宏实现
// 成员处理宏
#define CEREAL_MEMBER_NVP_NON_INTRUSIVE(member) ::cereal::make_nvp(#member, t.member)// 主序列化宏:非侵入的
#define CEREAL_SERIALIZE_NON_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar, const Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}// 主序列化宏:侵入的
#define CEREAL_SERIALIZE_INTRUSIVE(...) \
template <class Archive> \
void serialize(Archive& ar) { \ar( CEREAL_PASTE(CEREAL_NVP, __VA_ARGS__) ); \
}
2. 展开过程演示
struct Point
{float x, y, z;CEREAL_SERIALIZE_INTRUSIVE(x, y, z)
};

调用:CEREAL_SERIALIZE_INTRUSIVE(Point, x, y, z)
逐步展开:

// 步骤1: 替换为PASTE4宏
ar( CEREAL_PASTE4(CEREAL_NVP, x, y, z) );// 步骤2: 展开PASTE4
ar( CEREAL_NVP(x), CEREAL_EXPAND(CEREAL_PASTE3(CEREAL_NVP, y, z)) );// 步骤3: 展开内层EXPAND → 触发PASTE3
ar( ::cereal::make_nvp("x", t.x), CEREAL_PASTE3(CEREAL_NVP, y, z) );// 步骤4: 继续展开PASTE3
ar( ::cereal::make_nvp("x", t.x), ::cereal::make_nvp("y", t.y), ::cereal::make_nvp("z", t.z) );

⚠️ 注意事项

  1. 递归深度限制:

    • 预处理器递归层数通常为64层(编译器相关),超限需拆分参数或减少嵌套。
    • 更多层需要开启编译警告忽略。
  2. 兼容性:

    • __VA_ARGS__为C++11特性,需确保编译器支持。
  3. 调试技巧:

    • 使用gcc -E查看预处理结果,验证展开逻辑:
    g++ -E -P test.cpp | grep -A 10 "serialize"
    

💎 总结

通过引入CEREAL_EXPAND强制展开嵌套宏,解决了原方案中递归链断裂的问题。其核心原理是绕过预处理器的惰性展开机制,使内层宏作为独立标识符被处理。此方案在保持代码简洁性的同时,确保了任意数量参数的递归展开可靠性,为Cereal等库的宏封装提供了健壮基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88961.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14-C#的弹出的窗口输入与输出

C#的弹出的窗口输入与输出 1.文件名输入 string fileName Interaction.InputBox("输入保存的文件名", "保存");2.弹窗信息输出 MessageBox.Show("请选择轮询!", "Error", MessageBoxButtons.OK);catch (Exception ex){MessageBox.S…

多模态大语言模型arxiv论文略读(141)

Mini-InternVL: A Flexible-Transfer Pocket Multimodal Model with 5% Parameters and 90% Performance ➡️ 论文标题&#xff1a;Mini-InternVL: A Flexible-Transfer Pocket Multimodal Model with 5% Parameters and 90% Performance ➡️ 论文作者&#xff1a;Zhangwei …

VScode使用usb转网口远程开发rk3588

我使用的是鲁班猫的板&#xff0c;只有一个网口&#xff0c;需要接雷达&#xff0c;因此另外弄了一个usb转网口来连接电脑开发。 在使用vscode或MobaXterm连接板子时&#xff0c;使用主机名与用户名来连接&#xff1a; ssh catlubancat rk那边就直接插入usb转网口以及网线&a…

AUTOSAR图解==>AUTOSAR_AP_EXP_SOVD

AUTOSAR服务导向车辆诊断详解 面向现代化车辆架构的诊断方案 目录 1. 引言 1.1 ASAM SOVD简介1.2 SOVD产生的动机 2. SOVD参考架构 2.1 SOVD网关2.2 诊断管理器2.3 SOVD到UDS转换2.4 后端连接 3. SOVD用例 3.1 SOVD和UDS的共同用例3.2 SOVD特定用例 3.2.1 访问权限3.2.2 软件更…

第八讲:STL简介

1. 什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复的 组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 2. STL的版本 a. 原始版本 Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本…

高弹性、高可靠!腾讯云 TDMQ RabbitMQ Serverless 版全新发布

导语 2025年6月起&#xff0c;腾讯云 TDMQ RabbitMQ 版正式推出 Serverless 版本&#xff0c;该版本基于自研的存算分离架构&#xff0c;兼容 AMQP 0-9-1 协议和开源 RabbitMQ 的各个组件与概念&#xff0c;且能够规避开源版本固有的不抗消息堆积、脑裂等稳定性缺陷&#xff0…

Linux 内存调优之 BPF 分析用户态小内存分配

写在前面 博文内容为 使用 BPF 工具跟踪 Linux 用户态小内存分配(brk,sbrk)理解不足小伙伴帮忙指正 😃,生活加油我看远山,远山悲悯 持续分享技术干货,感兴趣小伙伴可以关注下 _ brk 内存分配简单概述 一般来说,应用程序的数据存放于堆内存中,堆内存通过brk(2)系统调用进…

心理测评app心理测试系统框架设计

一、逻辑分析 用户管理逻辑 新用户注册&#xff1a;需要收集用户的基本信息&#xff0c;如用户名、密码、邮箱等&#xff0c;并且要对输入信息进行合法性校验&#xff0c;确保信息完整且符合格式要求。同时&#xff0c;为每个新用户生成唯一的标识符&#xff0c;方便后续数据管…

配置有nvlink的H20A800使用pytorch报错

背景 装有nvlink的h20机器上配置好驱动和cuda之后使用pytorch报错 A800机器同样 (pytorch2.4) rootxx-dev-H20:~# python Python 3.12.0 | packaged by Anaconda, Inc. | (main, Oct 2 2023, 17:29:18) [GCC 11.2.0] on linux Type “help”, “copyright”, “credits” or …

sql的语句执行过程

第一步&#xff1a;客户端把语句发给服务器端执行 当我们在客户端执行SQL语句时&#xff0c;客户端会把这条SQL语句发送给服务器端&#xff0c;让服务器端的进程来处理这语句。也就是说&#xff0c;Oracle 客户端是不会做任何的操作&#xff0c;他的主要任务就是把客户端产生的…

深度学习-分类

深度学习-分类方式 &#xff08;重点&#xff09;一、按数据类型与处理逻辑分类1. 序列数据&#xff08;时序/顺序相关&#xff09;2. 网格状数据&#xff08;空间相关&#xff09;3. 图结构数据&#xff08;非欧几里得结构&#xff09;4. 其他特殊类型数据 &#xff08;重点&a…

C语言---常见的字符函数和字符串函数介绍

目录 前言 1 字符分类函数 2 字符转换函数 3 strlen的使用和模拟实现 3.1 strlen的模拟实现 4 strcpy的使用和模拟实现 4.1 strcpy的模拟实现 5 strcat的使用和模拟实现 5.1 strcat的模拟实现 6 strcmp的使用和模拟实现 6.1 strcmp的模拟实现 7 strncpy函数的使用…

Minio入门+适配器模式(实战教程)

一、安装Minio 1.1 拉取镜像 docker pull minio/minio docker images 1.2创建挂载目录 1.2.1 创建数据目录 mkdir -p /docker-minio/data 1.2.2 创建配置文件目录 mkdir -p /docker-minio/config 1.2.3 设置权限 chmod -R 777 /docker-minio/data /docker-minio/config …

LLaMA-Factory 对 omnisql 进行 ppo dpo grpo nl2sql任务 实现难度 时间 全面对比

在LLaMA-Factory框架下&#xff0c;针对omnisql任务&#xff08;自然语言到SQL生成&#xff09;应用PPO、DPO、GRPO三种算法的实现难度、时间及全面对比如下&#xff1a; 一、实现难度对比 1. PPO&#xff08;近端策略优化&#xff09; 难度&#xff1a;★★☆☆☆&#xff…

Kingbase 数据库中的 sys_guid() 函数报错

解决 Kingbase 数据库中的 sys_guid() 函数报错问题 问题背景 Kingbase 数据库在迁移或使用过程中&#xff0c;可能会遇到 select sys_guid() 函数报错 , 提示函数不存在的情况&#xff0c;这通常是由于以下几种原因造成的&#xff1a; 函数未正确安装或未启用函数参数不符合…

零基础RT-thread第五节:电容按键(2)

上一章的电容按键完全使用的HAL库的代码&#xff0c;并没有使用线程。这里尝试使用线程来控制电容按键。 依旧是 F767 本来以为会很容易实现&#xff0c;没想到尝试了很久&#xff0c;电容按键一直没有反应。 static rt_uint32_t measure_charge_time(void) {// 步骤1: 放电 …

华为云Flexus+DeepSeek征文|单机部署 与 CCE 高可用部署下 Dify 性能实测

引言 在当今的 AI 应用开发领域&#xff0c;选择合适的部署方式对于应用的性能表现、资源利用和成本控制至关重要。华为云为开发者提供了多样化的部署选择&#xff0c;其中基于单机 Flexus 实例的基础版部署和基于 CCE 容器的高可用版部署是两种常见的方式。本文将深入对比这两…

钉钉小程序框架:Pinia 状态管理与持久化存储封装

上一篇文章完成了 Pinia 在钉钉小程序中的引入与基础配置 文章地址&#xff1a;钉钉小程序框架引入 Pinia 状态管理-CSDN博客 本文将深入探讨如何通过Pinia 结合持久化存储 实现用户状态 在上一章节中&#xff0c;我们已经完成了 Pinia 在钉钉小程序中的引入与基础配置。本章将…

云计算产业链

一、云计算定义与分类体系 本质特征 按需服务模式&#xff1a;以网络化方式提供可配置的计算资源共享池&#xff08;网络/服务器/存储/应用&#xff09;。核心能力&#xff1a;快速弹性扩容、资源池化共享、按使用量付费、低管理开销。技术原理&#xff1a;通过分布式计算将大型…

git使用详解和示例

什么是 Git&#xff1f; Git 是一个 分布式版本控制系统&#xff08;DVCS&#xff09;&#xff0c;用于跟踪文件的变化&#xff0c;协调多人协作开发。由 Linus Torvalds 开发&#xff0c;用于管理 Linux 内核代码。 Git 的核心概念 名称说明工作区 (Working Directory)你看到…