C++串口写入速度慢于Python,求性能优化及代码修正方案
问题分析与优化方案
现有代码的核心错误
你的C++代码存在两个致命问题,直接导致发送数据错误和性能损耗:
- 发送内容错误:
serial.writeBytes(&result,sizeof(result))中,&result是std::string对象的内存地址,而非字符串内容的地址;sizeof(result)是string对象本身的大小(通常16/24字节),不是目标字符串的实际长度。这意味着你发送的不是"km.move(0,1) ",而是string对象的内部结构数据,接收端无法正确解析,同时额外发送了无效字节,增加了通信开销。 - 不必要的内存开销:每次调用
writedata都构造一个std::string,频繁的内存分配/释放会产生额外耗时。
优化后的串口写入代码
1. 修正基础写入逻辑
直接使用C字符串操作,避免不必要的string构造:
#include <cstring> // 用于strlen int serialib::writeBytes(const void *Buffer, const unsigned int NbBytes) { DWORD dwBytesWritten; if (!WriteFile(hSerial, Buffer, NbBytes, &dwBytesWritten, NULL)) return -1; // 检查是否全部写入,避免部分发送的情况 if (dwBytesWritten != NbBytes) return -2; // 表示部分写入 return 0; // 0表示成功,更符合常规错误码逻辑 } void writedata(const char *arg) { size_t len = strlen(arg); serial.writeBytes(arg, len); } int main() { serial.openDevice("COM3", 115200); if (!serial.isDeviceOpen()) { return 1; } // 配置串口超时,减少写入延迟 COMMTIMEOUTS timeouts = {0}; timeouts.WriteTotalTimeoutConstant = 0; // 写入无固定超时 timeouts.WriteTotalTimeoutMultiplier = 0; // 写入无乘数超时 SetCommTimeouts(serial.hSerial, &timeouts); // 循环发送 const char* cmd = "km.move(0,1) "; for (int i = 1; i <= 1000; ++i) { writedata(cmd); } }
2. 进一步性能优化:批量发送
如果接收端支持批量处理命令,可以将多个命令拼接成一个缓冲区,减少WriteFile的系统调用次数(系统调用本身有开销):
int main() { serial.openDevice("COM3", 115200); if (!serial.isDeviceOpen()) { return 1; } COMMTIMEOUTS timeouts = {0}; timeouts.WriteTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; SetCommTimeouts(serial.hSerial, &timeouts); // 预拼接1000条命令,一次性发送 const char* cmd = "km.move(0,1) "; size_t cmd_len = strlen(cmd); std::string batch; batch.reserve(cmd_len * 1000); // 预分配内存,避免多次扩容 for (int i = 1; i <= 1000; ++i) { batch += cmd; } serial.writeBytes(batch.c_str(), batch.size()); }
其他性能提升要点
- 关闭不必要的流量控制:确保串口未启用XON/XOFF或硬件流控,这类机制会增加通信延迟。
- 检查驱动配置:部分串口驱动默认启用了Nagle类算法,可尝试通过驱动设置或
SIO_SET_TCP_NODELAY控制码禁用(需根据硬件驱动支持情况调整)。 - 异步写入(高阶优化):如果对性能要求极高,可使用
WriteFile的异步模式(传递OVERLAPPED结构),避免线程阻塞等待写入完成,但会增加代码复杂度。
内容的提问来源于stack exchange,提问作者kkyareuk
相关产品推荐
相关产品推荐

