前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从Python传递参数到C++

从Python传递参数到C++

作者头像
王云峰
发布2023-10-21 16:30:22
2460
发布2023-10-21 16:30:22
举报
文章被收录于专栏:Yunfeng's Simple Blog

概述

有些场景下,需要将Python里面计算得到的参数或者结果传入到C++来进行工程部署。一个常见问题是,Python该以什么格式 (二进制还是文本) 保存这些参数,然后从C++代码里面来读取呢,各有什么优劣?这里我们简单实验一下,并写一些趁手的代码,供查阅。

二进制格式和文本格式对比

假设我们有一组参数是存储在Numpy的ndarray格式中的,为了在C++中使用,我们需要保存它们到硬盘的文件中。一般有两种保存方法:二进制文件保存和文本文件保存。

假设我们有一个1024x1024的浮点型参数待保存:

代码语言:javascript
复制
params = np.random.rand(1024, 1024).astype('float32')

二进制保存很简单,直接调用Numpy的tofile文件即可:

代码语言:javascript
复制
params.tofile("params.bin")

如果用文本文件保存,有两种保存方式,分别为调用savetxt函数和将每个值转换为str并用分隔符分开依次存入文件:

代码语言:javascript
复制
# 文本文件保存方式1
np.savetxt("params_1.txt", params)

# 文本文件保存方式2
delimiter = " "
with open("params_2.txt", "w") as f:
    for p in params:
        f.write(str(p) + delimiter)

猜猜看这三种情况分别大小是多少?

结论如下:

代码语言:javascript
复制
4.0M params.bin
25M params_1.txt
11M params_2.txt

可以看到,二进制格式存储空间是最小的,分别是两种文本形式存储空间的16%和36%,存储压缩比例还是比较明显的。

因此推荐以二进制形式存储, 存储脚本简单总结如下:

代码语言:javascript
复制
import numpy as np

# rand默认格式是float64,我们使用float32就可以
params = np.random.rand(1024, 1024).astype("float32")

# 拉平成一维,为了在C++里面方便处理
params = params.flatten()

params.tofile("params.bin")

C++ 读取二进制文件

C++ 去读二进制的代码如下:

代码语言:javascript
复制
#include <fstream>
#include <iostream>
#include <string>

void read_binary(const std::string &file_path, float *data, int size) {
  std::ifstream in_file;
  in_file.open(file_path, std::ios::binary | std::ios::in);
  in_file.read((char *)data, size * sizeof(float));
  in_file.close();
}

int main() {
  std::string file_path = "params.bin";
  int size = 1024 * 1024;

  // 使用stack上空间来创建数组,有大小限制,不推荐
  // float params[size];

  // 使用new来构建heap上空间, 无大小限制,但需要自己释放内存
  float *params = new float[size];
  read_binary(file_path, params, size);

  // 打印前10个参数
  for (int i = 0; i < 10; i++) {
    std::cout << params[i] << std::endl;
  }

  delete[] params;
}

注意新建数组的时候,有在栈上或者堆上构建两种方式,栈上构建有大小限制,如果数组维度太大就会报错,如下面的代码:

代码语言:javascript
复制
#include <iostream>
int main() {
        int arr[1024*1024*1024];

        return 0;
}

运行会报错:

代码语言:javascript
复制
$ g++ stack_over.cpp && ./a.out
[1]    89415 segmentation fault  ./a.out

因此推荐用堆上创建数组,详见上述代码的注释。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 二进制格式和文本格式对比
  • C++ 读取二进制文件
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档