使C解析器高效 [英] Making C parser efficient
问题描述
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define CliMaxSize 1024
#define PacketMaxSize 999
#define MaxNumberofPackets 5
#if 1
static char InData[CliMaxSize] = "\r\nRCV\r\nSOME:DATA40\r\n24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x\r\nOK\r\n\r\nRCV\r\nSOME:DATA50\r\n24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngk\r\nOK\r\n\r\nRCV\r\nSOME:DATA0\r\n\r\nOK\r\n";
#endif
#if 0
static char InData[CliMaxSize] = "\r\nRCV\r\nSOME:DATA40\r\n24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x\r\nOK\r\n\r\nRCV\r\nSOME:DATA60\r\n24Ab246324400123543gfdsas4sdaasd";
#endif
static char PacketBytes[PacketMaxSize];
typedef struct {
unsigned char ValidPackets;
unsigned char DataSizeStartAddress[MaxNumberofPackets];
unsigned char ValidPacketsStartAddress[MaxNumberofPackets];
unsigned int DataSize[MaxNumberofPackets];
}_CLI;
static unsigned char AvailableValidPackets(_CLI *const PtrCLI) {
char *pch;
PtrCLI->ValidPackets = 0;
pch = strstr(InData,"OK\r\n");
while (pch != NULL) {
PtrCLI->ValidPackets++;
pch = strstr(++pch,"OK\r\n");
}
return PtrCLI->ValidPackets;
}
static void GetStartAddressOfPackets(_CLI *const PtrCLI) {
char *pch = &InData[0];
unsigned char LocalCounter = 0;
/* find the location of ":" in Source */
while (*pch++ != '\0') {
if (*pch == ':') {
PtrCLI->ValidPacketsStartAddress[LocalCounter] = pch - &InData[0] + 9;
PtrCLI->DataSizeStartAddress[LocalCounter] = pch - &InData[0] + 5;
LocalCounter++;
}
}
}
static void ExtractDataSizeInIntegerForm(_CLI *const PtrCLI) {
char LocArray[MaxNumberofPackets] = { 0,0,0,0,0};
char LocCounter = 0, LocalDummy = 0, localMultiplier = 1;
for (char LocLoop = 0; LocLoop < PtrCLI->ValidPackets; LocLoop++) {
char *LocPtr = (char*)&InData[PtrCLI->DataSizeStartAddress[LocLoop]];
while (*LocPtr != '\r') {
LocArray[LocCounter++] = *(LocPtr++) - '0';
localMultiplier *= 10;
}
for (char c = 0; c < LocCounter; c++){
localMultiplier = localMultiplier / 10;
LocalDummy += LocArray[c] * localMultiplier;
LocArray[c] = 0;
}
PtrCLI->DataSize[LocLoop] = LocalDummy;
LocCounter = 0;
LocalDummy = 0;
}
}
static void CopyString(const int StartAddress, const int size) {
char *ptr = &InData[0] + StartAddress;
memset(PacketBytes, '\0', sizeof(PacketBytes));
for(char i = 0; i < size; i++) {
PacketBytes[i] = *ptr++;
}
}
static void ExtractPackets (_CLI *const PtrCLI){
for(char i = 0; i< PtrCLI->ValidPackets; i++) {
if (PtrCLI->DataSize[i] != 0) {
CopyString(PtrCLI->ValidPacketsStartAddress[i], PtrCLI->DataSize[i]);
printf("Packet %d> size: %d data: ",i+1, PtrCLI->DataSize[i]);
for (char j = 0; j< PtrCLI->DataSize[i]; j++)
{
printf("%c", PacketBytes[j]);
}
printf("\n");
}
else {
printf("Packet %d> size: %d data: \n",i+1, PtrCLI->DataSize[i]);
}
}
}
int main() {
_CLI CommandLineInterface;
AvailableValidPackets(&CommandLineInterface);
GetStartAddressOfPackets(&CommandLineInterface);
ExtractDataSizeInIntegerForm(&CommandLineInterface);
ExtractPackets(&CommandLineInterface);
return 0;
}
我的尝试:
我正在制作这个解析器并根据需要输出:
数据包1>尺寸:40数据:24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0xPacket 2>尺寸:50数据:24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngkPacket 3>大小:0数据:
但我的主管要求我提高效率。你们中的任何人都可以提出一些建议,让它变得更好更短吗?
任何建议都将受到赞赏。
What I have tried:
I am making this parser and the output is as required:
Packet 1> size: 40 data: 24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x
Packet 2> size: 50 data: 24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngk
Packet 3> size: 0 data:
but my supervisor is asking me to make it more efficient. can anyone of you give some suggestions to make it better and short?
any suggestion will be appreciated.
推荐答案
你可以结合AvailableValidPackets
和GetStartAddressOfPackets
很容易。另外要对它进行更优化,对所有输入数据进行一次迭代,而不是使用strstr,并一次性进行解析,计数等。
You can combineAvailableValidPackets
andGetStartAddressOfPackets
easily. Also to optimized it more, have one single iteration over all input data instead of using strstr and do parsing, counting etc. in one go.
static void CopyString(const int StartAddress,const int size){
char * ptr =& InData [0] + StartAddress;
memset(PacketBytes,'\ 0',sizeof(PacketBytes));
for(char i = 0; i< size; i ++){
PacketBytes [i] = * ptr ++;
}
}
static void CopyString(const int StartAddress, const int size) {
char *ptr = &InData[0] + StartAddress;
memset(PacketBytes, '\0', sizeof(PacketBytes));
for(char i = 0; i < size; i++) {
PacketBytes[i] = *ptr++;
}
}
我看不到为了将 PacketBytes
缓冲区置零,代码会立即覆盖它。
I see no purpose in zeroing the PacketBytes
buffer, the code is immediately overwriting it.
这篇关于使C解析器高效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!