“IQ波形文件生成器”C++实现和Python实现的对比

本文对比了C++和Python在实现IQ波形文件生成器时的编码效率、运行效率和内存占用。实验结果显示,Python在读取多个文件时效率更高,而C++代码更紧凑。C++程序用时9.66553s,Python程序用时4.221034s,且Python代码仅有25行,远少于C++的109行。尽管C++性能差异不大,但Python在开发效率上占据优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    本文主要借助我在项目中编写的一个小软件,来对一窥C++实现和Python实现在“编码效率”、“运行效率”、“内存占用”等方面的差异。当然,这个对比只是针对这类项目,不具普遍性。


一、问题

    将两个几M大小的文本格式txt文件(一个存储的是float型的I路数据,另一个存储的是float型的Q路数据)合成一个二进制格式的bin文件(波形文件)。以本次实验的“bt_wave_i.txt”和“bt_wave_q.txt”为例:

                                 


如上图所示,这是用notepad++打开的部分数据截图,灰色部分是行号。两个文件的数据行是相等的,大约有450,000行。


二、对比

1,性能对比

           

    

    上图是使用Process Explorer捕获的C++程序和python程序运行高峰期的性能截图。左图是C++的,看的是Release版本,右图

clc; clear; close all; warning off; addpath(genpath(pwd)); rng(‘default’) % 重置随机数生成器的种子,以获得重复的随机数序列 %MATLAB/verilog/python/opencv/tensorflow/caffe/C/C++等算法仿真 SNR = 12;% 信噪比(Signal-to-Noise Ratio) % 不同调制类型的分类变量 modulationTypes1 = categorical([“QPSK”,“BPSK”]); modulationTypes2 = categorical([“QPSK”,“BPSK”]); nFrames = 150; % 总帧数 Trainingdata = 80; % 用于训练的帧数 Testingdata = 10; % 用于测试的帧数 TestSamples = 10; % 每个测试帧的样本数 sps = 8; % 每个符号的样本数(Samples per symbol) spf = 1024; % 每个帧的样本数(Samples per frame) symbolsPerFrame = spf / sps; % 每个帧中的符号数 fs = 1e6; % 采样率(Sample rate) fc = [900e6 100e6]; % 中心频率(Center frequencies) rangeFc = [fs/6, fs/5]; % 中心频率范围(Center frequency (Hz) range) % AWGN信道对象 awgnChannel = comm.AWGNChannel(‘NoiseMethod’, ‘Signal to noise ratio (SNR)’, ‘SignalPower’, 1, ‘SNR’, SNR) % 多径信道对象 multipathChannel = comm.RicianChannel(‘SampleRate’, fs, ‘PathDelays’, [0 1.8 3.4]/fs,‘AveragePathGains’, [0 -2 -10], ‘KFactor’, 4, ‘MaximumDopplerShift’, 4) % 最大频偏 maxDeltaOff = 5; % 随机产生频偏 deltaOff = (rand()2maxDeltaOff) - maxDeltaOff; % 频率系数 C = 1 + (deltaOff/1e6); % 频率偏移 offset = -(C-1)*fc(1); % 频率偏移对象 frequencyShifter = comm.PhaseFrequencyOffset(‘SampleRate’, fs,‘FrequencyOffset’, offset); % 自定义测试信道对象 channel = helperModClassTestChannel(… ‘SampleRate’, fs, … ‘SNR’, SNR, … ‘PathDelays’, [0 1.8 3.4] / fs, … ‘AveragePathGains’, [0 -2 -10], … ‘KFactor’, 4, … ‘MaximumDopplerShift’, 4, … ‘MaximumClockOffset’, 5, … ‘CenterFrequency’, 900e6); rng(1); % 设置随机数生成器的种子为1,用于生成可重复的随机数序列 tic; % 记录开始时间 % 不同调制类型的数量 numModulationTypes1 = length(modulationTypes1); numModulationTypes2 = length(modulationTypes2); % 初始化用于存储帧数据的对象 frameStore1 = helperModClassFrameStore(nFramesnumModulationTypes1,spf,modulationTypes1); frameStore2 = helperModClassFrameStore(nFramesnumModulationTypes2,spf,modulationTypes1); % 传输延迟(跳过前50个样本,用于减小边缘效应) transDelay = 50; for modType2 = 1:numModulationTypes1 modType2% 显示当前调制类型 numSymbols1 = (nFrames / sps);% 每种调制类型的符号数 % 获取当前调制类型的原始数据生成器 dataSrc2 = getSource(modulationTypes2(modType2), sps, 2*spf, fs); % 获取当前调制类型的调制器 modulator1 = getModulator(modulationTypes2(modType2), sps, fs, SNR); % 如果是B-FM、DSB-AM或SSB-AM调制类型 if contains(char(modulationTypes2(modType2)), {‘B-FM’,‘DSB-AM’,‘SSB-AM’}) channe2.CenterFrequency = 100e6;% 设置信道的中心频率为100MHz else channe2.CenterFrequency = 900e6;% 设置信道的中心频率为900MHz end for p=1:nFrames% 生成每种调制类型的帧 x2 = dataSrc2();% 生成原始数据 % 调制 y2 = modulator1(x2);% 将原始数据调制为射频信号 if contains(char(modulationTypes2(modType2)), {'LFM'})% 如果是LFM调制类型 release(channe2);% 释放信道对象,用于刷新其状态 end rxSamples2 = channel(y2+y1);% 经过信道传输,得到接收到的信号 % 组织接收到的信号为帧 frame2 = helperModClassFrameGenerator(rxSamples2, spf, spf, transDelay, sps); % 将帧数据存储到frameStore1中,并标记其对应的调制类型 add(frameStore2, frame2, modulationTypes2(modType2)); end end % 将帧数据集frameStore按照给定的比例分割为训练数据集mcfsTraining、验证数据集mcfsValidation测试数据集mcfsTest [mcfsTraining,mcfsValidation,mcfsTest] = splitData(frameStore2,[Trainingdata,Testingdata,TestSamples]); % 设置训练数据集的输出格式为"IQAsPages",并获取训练数据对应的标签 mcfsTraining.OutputFormat = “IQAsPages”; [rxTraining,rxTrainingLabel] = get(mcfsTraining); % 设置验证数据集的输出格式为"IQAsPages",并获取验证数据对应的标签 mcfsValidation.OutputFormat = “IQAsPages”; [rxValidation,rxValidationLabel] = get(mcfsValidation); % 设置测试数据集的输出格式为"IQAsPages",并获取测试数据对应的标签 mcfsTest.OutputFormat = “IQAsPages”; [rxTest,rxTestLabel] = get(mcfsTest); % 绘制测试数据的时域波形图,并根据标签显示不同调制类型的波形 figure plotTimeDomain(rxTest,rxTestLabel,modulationTypes2,fs) % 绘制测试数据的频谱图,并根据标签显示不同调制类型的频谱 figure plotSpectrogram(rxTest,rxTestLabel,modulationTypes2,fs,sps) title(“Test Label Distribution”)给我把训练集以语谱图的形式保存到指定文件夹中
03-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值