c++雅兰亭库 (yalantinglibs) 介绍及使用(序列化、json和结构体转换、协程)

news2024/11/25 2:52:13

雅兰亭库(yalantinglibs)介绍

雅兰亭库,名字很优雅,也很强大。它是阿里开源的一个现代C++基础工具库的集合, 现在包括 struct_pack, struct_json, struct_xml, struct_yaml, struct_pb, easylog, coro_rpc, coro_io, coro_http 和 async_simple等功能, 也一直在持续优化并添加更多的新功能。

yaLanTingLibs 的目标::为C++开发者提供高性能,极度易用的现代C++基础工具库, 帮助用户构建高性能的现代C++应用。

yalantinglibs开源地址:

https://github.com/alibaba/yalantinglibs

更多内容参见官方文档介绍:

雅兰亭库 | A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.

编译器要求

 如果你的编译器只支持C++17,yalantinglibs 只会编译序列化库(struct_*系列,只能使用struct_*系列的功能如快速序列化,结构体和json的相互转换等)。如果你的编译器低于C++17,那么只围观下可以,用不了。也建议升级使用C++17及以上版本,目前来说C++17已经很常用了。

确保你的编译器版本不低于:

  • clang6++ (libstdc++-8 以上)。
  • g++9 或更高版本。
  • msvc 14.20 或更高版本。

如果你的编译器支持C++20,yalantinglibs会编译全部库。

确保你的编译器版本不低于:

  • clang11++ (libstdc++-8 以上)。
  • g++10 或更高版本。
  • msvc 14.29 或更高版本。

可以手动指定Cmake选项-DENABLE_CPP_20=ON 或 -DENABLE_CPP_20=OFF来控制。

安装&编译​

Yalantinglibs 是一个head-only的库,这意味着你可以简单粗暴的直接将./include/ylt拷贝走。但是更推荐的做法还是用Cmake安装。

  • 克隆仓库
git clone https://github.com/alibaba/yalantinglibs.git
  • 构建,测试并安装

  • 建议最好在安装之前编译样例/压测程序并执行测试:

cmake ..
cmake --build . --config debug # 可以在末尾加上`-j 选项, 通过并行编译加速
ctest . # 执行测试

测试/样例/压测的可执行文件存储在路径./build/output/下。

  • 你也可以跳过编译:
# 可以通过这些选项来跳过编译样例/压测/测试程序
cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_BENCHMARK=OFF -DBUILD_UNIT_TESTS=OFF
cmake --build .
  1. 默认情况下会安装到系统默认的include路径,你也可以通过选项来自定义安装路径。
cmake --install . # --prefix ./user_defined_install_path
  1. 开始编程
  • 使用CMAKE:

安装完成后,你可以直接拷贝并打开文件夹src/*/examples,然后执行以下命令:

mkdir build
cd build
cmake ..
cmake --build .
  • 手动编译:
  1. 将 include/加入到头文件包含路径中(如果已安装到系统默认路径,可跳过该步骤)
  2. 将 include/ylt/thirdparty 加入到头文件包含路径中(如果已通过Cmake 选项 -DINSTALL_INDEPENDENT_THIRDPARTY=ON 安装了第三方依赖,可跳过该步骤)
  3. 如果你使用了 coro_ 开头的任何头文件, 在linux系统下需要添加选项 -pthread . 使用g++编译器时需要添加选项 -fcoroutines
  4. 全部搞定. 更多细节请参考 example/cmakelist.txt.
  • 更多细节: 如需查看更多细节, 除了example/cmakelist.txt

cmake中使用

 前提是已经过前面步骤的构建,使用 cmake 在项目中导入 ylt 的示例:

cmake_minimum_required(VERSION 3.15)
project(file_transfer)
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Threads REQUIRED)
link_libraries(Threads::Threads)
find_package(yalantinglibs REQUIRED)
link_libraries(yalantinglibs::yalantinglibs)

add_executable(coro_io_example main.cpp)

struct_pack​

struct_pack是一个基于编译期反射,易用且高性能的序列化库,head-only。一行代码即可完成序列化/反序列化。性能远超protobuf等传统序列化库。

// 定义一个C++结构体
struct person {
  int64_t id;
  std::string name;
  int age;
  double salary;
};
// 初始化对象
person person1{.id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42};

// 一行代码序列化
std::vector<char> buffer = struct_pack::serialize(person1);

// 一行代码反序列化
auto person2 = deserialize<person>(buffer);

struct_pack 性能优异,最快比protobuf 高一个数量级,但是之前struct_pack 是C++20 开发的,只支持C++20 编译器,并且只支持aggregate 类型的序列化反序列化,为了让更多低版本编译器的用户也能使用struct_pack,现在支持了C++17 。

struct_json​

基于反射的json库,轻松实现结构体和json之间的映射。

#include "ylt/struct_json/json_reader.h"
#include "ylt/struct_json/json_writer.h"

struct person {
  std::string name;
  int age;
};
REFLECTION(person, name, age);

int main() {
  person p{.name = "tom", .age = 20};
  std::string str;
  struct_json::to_json(p, str); // {"name":"tom","age":20}

  person p1;
  struct_json::from_json(p1, str);
}

json 解析benchmark 

struct_json 不但易用性更好,性能上也比rapidjson更高。

img

struct_json 解析10个文件的速度全面领先rapidjson,其中在解析gsoc-2018.json 文件的时候struct_json 性能是rapidjson 的6.3倍,说明struct_json 不仅仅在易用性和安全性上更好,性能上也不错。

struct_json, struct_xml, struct_yaml 正是为了让我们从繁琐不安全的手写代码中解放出来,通过结构体实现序列化和反序列化的自动化,安全可靠,性能还更好,是时候用它们去替代经典的rapidxxx系列啦。

coro_rpc​

coro_rpc是用C++20开发的基于无栈协程和编译期反射的高性能的rpc库,在单机上echo测试qps达到2000万(详情见benchmark部分) ,性能远高于grpc和brpc等rpc库。然而高性能不是它的主要特色,coro_rpc的主要特色是易用性,免安装,包含头文件就可以用,几行代码就可以完成一个rpc服务器和客户端。

coro_rpc的设计理念是:以易用性为核心,回归rpc本质,让用户专注于业务逻辑而不是rpc框架细节,几行代码就可以完成rpc开发。 rpc的本质是什么?rpc的本质就是一个远程函数,除了rpc底层的网络IO之外,其它的就和普通函数一样。用户不需要关注rpc底层的网络IO、路由、序列化等细节,用户只需要专注于rpc函数的业务逻辑即可,这就是coro_rpc的设计理念, 正是基于这一设计理念,coro_rpc提供了非常简单易用的API给用户使用。通过一个例子来看看coro_rpc的易用性如何。

rpc使用​

1.定义rpc函数

// rpc_service.hpp
inline std::string echo(std::string str) { return str; }

2.注册rpc函数和启动server

#include "rpc_service.hpp"
#include <ylt/coro_rpc/coro_rpc_server.hpp>

int main() {

  // 初始化服务器
  coro_rpc_server server(/*thread_num =*/10, /*port =*/9000);

  server.register_handler<echo>(); // 注册rpc函数

  server.start(); // 启动server并阻塞等待
}

对于rpc服务端来说,用户只需要定义rpc函数再启动server即可,不需要关注其它细节,5,6行代码就可以提供一个rpc服务了,是不是很简单!再来看看client是怎么调用hello这个rpc服务的。

rpc_client端

  1. 连接服务端
  2. rpc调用
#include "rpc_service.hpp"
#include <ylt/coro_rpc/coro_rpc_client.hpp>

Lazy<void> test_client() {
  coro_rpc_client client;
  co_await client.connect("localhost", /*port =*/"9000");

  auto r = co_await client.call<echo>("hello coro_rpc"); //传参数调用rpc函数
  std::cout << r.result.value() << "\n"; //will print "hello coro_rpc"
}

int main() {
  syncAwait(test_client());
}

client调用rpc函数也同样简单,5,6行代码就可以实现rpc调用了。 就像调用本地函数一样调用远程rpc函数,在call里面输入函数名字和参数就可以实现远程调用了,非常简单。

上面的这个简单的例子已经充分展示了coro_rpc的易用性和特点了,也体现了rpc的本质,即用户可以像调用本地函数那样调用远程函数,用户只需要关注rpc函数的业务逻辑即可。

coro_rpc的接口易用性还体现在rpc函数几乎没有任何限制,rpc函数可以拥有任意多个参数,参数的序列化和反序列化由rpc库自动完成,用户无需关心。

和grpc、brpc比较易用性​

rpc易用性比较​

RPC是否需要定义DSL是否支持协程hello world例子代码行数依赖库是否header only
grpcYesNo70+ helloworld16No
brpcYesNo40+ helloworld6No
coro_rpcNoYes93Yes

c++未来演化

如果说C++11是C++的一个里程碑,那么C++20就是现代C++的一个里程碑。因为它引入了非常重要的几个特性,而这将改变C++的编程理念和模型,当然也让C++变得更加好用,比如Concepts、Modules、Coroutine、Ranges等。以协程(Coroutine)为例,它可以让我们用同步方式写异步代码,彻底摆脱了回调地狱(Callback Hell),异步回调模型将被协程代替。用C++20新标准,失去的是弯弯绕绕的Callback,得到的是简单直接的协程。协程让异步变得简单,在未来3~5年,C++网络库的协程化将是大势所趋。

Modules让我们不用再引入include头文件了,而是像其他语言一样使用import库就好,同时它还会大大提升编译速度。将async_simple[2] 模块化后,编译速度提升了45%,性能也略有提升。可以说,Modules带来了C++统一包管理的曙光。

C++新标准的演进速度比较快,从C++11开始保持着三年一个版本的迭代速度,后面还有C++23/26/29。而未来C++标准将提供更多好东西,比如Executors、Networking、编译期反射等。虽然新标准推出比较快,但基于新标准的库却跟不上,比如协程库,目前除了async_simple外,能用的无栈协程库几乎没有,这也是C++的遗留问题。

其他资源

json与C++结构体互相转换_c++ 结构体 转 json_xyz347的博客-CSDN博客

高效工具推荐----vcpkg - 知乎

反射实现无侵入式序列化_yalantinglibs_故人帝梦的博客-CSDN博客

Github C++项目积累_xupeng1644的博客-CSDN博客

iguana反射功能 - 知乎

purecpp - a cool open source modern c++ community 

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

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

相关文章

斗象科技-2023攻防演练必修高危漏洞集合下载(2个版本)

高危风险漏洞一直是企业网络安全防护的薄弱点&#xff0c;也成为HW 攻防演练期间 红队的重要突破口&#xff1b;每年HW 期间爆发了大量的高危风险漏洞成为红队突破网络 边界防护的一把利器&#xff0c;很多企业因为这些高危漏洞而导致整个防御体系被突破、 甚至靶标失守而遗憾出…

TepeScript 问题记录

问题 对object的所有属性赋值或清空&#xff0c;提示类型错误不能赋值 type VoiceParams {_id?: string | undefined;name: string;sex: string;vc_id: string;model_url: string;preview_url: string;isPrivate: boolean;visible: boolean; }const formData reactive<V…

AI绘画网站都有哪些比较好用?

人工智能绘画网站是一种利用人工智能技术进行图像处理和创作的网站。这些绘画网站通常可以帮助艺术家以人工智能绘画的形式快速生成有趣、美丽和独特的绘画作品。无论你是专业的艺术家还是对人工智能绘画感兴趣的普通人&#xff0c;人工智能绘画网站都可以为你提供新的创作灵感…

痛点缠身的科沃斯!如何重回“扫地茅”?

一度被称为扫地机器人代名词的“扫地茅”科沃斯&#xff0c;尽管仍处于头部阵营的头部&#xff0c;但是从多个角度来看&#xff0c;科沃斯的现状却也称得上是痛点缠身。 而对于这个曾经将扫地机产品带入国内大众视野、完成了用户认知培养的领跑者&#xff0c;到底应该如何去直…

ddia(3)----Chapter3. Storage and Retrieval

However, first we’ll start this chapter by talking about storage engines that are used in the kinds of databases that you’re probably familiar with: traditional relational databases, and also most so-called NoSQL databases. We will examine two families o…

【C语言学习】函数原型

函数原型 代码一 #include<stdio.h> void sum(int begin, int end) {int i;int sum 0;for(ibegin; i<end; i){sum sum i;}printf("%d到%d的和是%d\n", begin, end, sum); }int main() {sum(1,10);sum(20,30);sum(40,50);return 0; }代码二&#xff08;函…

Camunda 7.x 系列【12】创建流程引擎

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. ProcessEngine2. 创建流程引擎2.1 Java API2.2 XML 配置2.3 Spring2.4 Spring Boot1. Pr…

大专非科班转码成功自白

大专非科班转码成功自白 文章目录 大专非科班转码成功自白初步学习进阶学习提供阶段面试阶段总结 2023年是博主从业18年以来找工作最难的一年。但程序员这个行业还是被很多毕业生青睐。就业相对比较好&#xff0c;收入相对比较高&#xff0c;虽然面临996&#xff0c;依然给很多…

外来jar包运行项目,更换部分文件重新压缩成jar包部署运行

跟公司一个外部支援同事合作开发&#xff0c;发包版本在他那里&#xff0c;功能开发工作我来做&#xff0c;可能是因为我是后来加入的&#xff0c;他不想把代码交到公司来&#xff0c;每次要发布新版本急于测试&#xff0c;联系他发包一直不回复消息&#xff0c;打电话也不接&a…

面试易考:多线程模式下的单例模式两种具体实现(饿汉,懒汉),两个的线程安全性,阻塞队列,生产者消费者模型

补充&#xff1a;synchron(锁对象&#xff09;&#xff1a;给对象里面做了一个标记&#xff0c;每个对象&#xff0c;除了代码中写的属性外&#xff0c;此外还有一部分空间&#xff0c;存储的是标志位&#xff0c;这个标志位相当于是加锁&#xff0c;当这一位被标记加锁之后&am…

项目实战 — 消息队列(7){虚拟主机设计(2)}

目录 一、消费消息的规则 二、消费消息的具体实现方法 &#x1f345; 1、编写消费者类&#xff08;ConsumerEnv&#xff09; &#x1f345; 2、编写Consumer函数式接口&#xff08;回调函数&#xff09; &#x1f345; 3、编写ConsumeerManager类 &#x1f384;定义成员变…

Linux系统下安装配置 Nginx 超详细图文教程

Linux系统下安装配置 Nginx 详细教程介绍 一、下载 Nginx 安装包 打开Nginx官网 &#xff1a;http://nginx.org/en/download.html 然后我们找到一个版本&#xff0c;把鼠标移动到上面&#xff0c;右键 - 复制链接地址 我们使用 wget 命令把Nginx安装包下载到/usr/local/目录中…

微信小程序实现当前页面更新上一个页面

日常项目中需要实现的一个价格脱敏功能&#xff1a;通过点击页面二中的查看完整信息 点击回退按钮实现页面一中的价格显露出来 通过查询了大量资料发现 大多数都是通过调用上一个接口的onload 或者onshow 实现视图更新 经测试后 发现 无法实现 只能更改数据 无法更新视图 实现…

shell脚本条件测试语句,if,case

shell脚本条件测试语句&#xff0c;if&#xff0c;case 一.条件测试1.1test命令1.2文件测试1.2.1文件测试常见选项 1.3数值比较1.4字符串比较1.5逻辑测试 二.if语句2.1单分支结构2.3多分支 三.case语句 一.条件测试 1.1test命令 测试特定的表达式是否成立&#xff0c;当条件成…

InVEST模型使用

第一天&#xff1a; 1. 生态系统服务理论联系实践案例讲解 2. InVEST模型的开发历程、不同版本的差异及对数据需求的讲解 3. InVEST所需数据的要求&#xff08;分辨率、格式、投影系统等&#xff09;、获取及标准化预处理讲解 4. InVEST运行常见问题及处理解决方法讲解 5.…

【C++】数据结构与算法:常用查找算法

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍常用查找算法。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#x1…

【果树农药喷洒机器人】Part6:静态PWM变量喷药实验

文章目录 一、引言二、静态PWM变量喷药实验2.1搭建喷药实验平台2.2变量喷药控制实验 一、引言 为综合评估所设计的果树喷药机器人变量喷药效率和质量&#xff0c;验证系统的控制性能和实际作业的可行性&#xff0c;本章开展果树变量喷药实验。首先&#xff0c;通过静态的PWM变…

Mongodb 分页查询数据重复

&#xff08;学习的本质&#xff0c;不在于记住哪些知识&#xff0c;而在于它触发了你的思考——迈克尔桑德尔&#xff09; mongodb排序的限制 相关链接 最多对32个键进行排序排序一致性 其中排序一致性指的是&#xff0c;如果被排序的字段值是重复的&#xff0c;那么在进行…

不同路径数

希望这篇题解对你有用&#xff0c;麻烦动动手指点个赞或关注&#xff0c;感谢您的关注~ 不清楚蓝桥杯考什么的点点下方&#x1f447; 考点秘籍 想背纯享模版的伙伴们点点下方&#x1f447; 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不能错过的模板大全…

C指针:程序员的神奇箭头,穿越内存的冒险之旅!

目录 &#x1f575;️‍♂️ 引言&#xff1a;指针&#xff0c;那些指向星星的小箭头&#xff01; 一、&#x1f3af; 探索箭头&#xff1a;指针的基础知识 1.1 指针是什么&#xff1f; 1.2 解引用操作符&#xff1a;* 是关键 1.3 指针的比较和运算 1.4 空指针&#xff1a…