优化语法分析器函数c程序
你好, 我想知道我是否可以再优化这段代码。由于这是在一个快速的事务服务器中,因此每秒将有许多调用。因此解析器必须非常快速和优化 我不知道我能不能改进一下 包含测试用例的完整代码。我想优化的是函数优化语法分析器函数c程序,c,optimization,C,Optimization,你好, 我想知道我是否可以再优化这段代码。由于这是在一个快速的事务服务器中,因此每秒将有许多调用。因此解析器必须非常快速和优化 我不知道我能不能改进一下 包含测试用例的完整代码。我想优化的是函数g\u get\u dnis\u user\u part 我希望这是正确的论坛张贴 gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) c89 #包括 #包括 #包括 #ifndef FALSE #定义FALSE 0 #恩迪夫 #如果是真的 #定义真1 #恩迪夫 静态i
g\u get\u dnis\u user\u part
我希望这是正确的论坛张贴
gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
c89
#包括
#包括
#包括
#ifndef FALSE
#定义FALSE 0
#恩迪夫
#如果是真的
#定义真1
#恩迪夫
静态int g_get_dnis_user_part(const char*dnis,char*user_part,size\t size);
内部主(空)
{
/*测试用例*/
const char*dnis_test1=”0846372573@10.1.8.34";
const char*dnis_test2=“084637257310.1.8.34”;
const char*dnis_test3=”084e672573@10.1.8.34";
const char*dnis_test4=“”;
const char*dnis_test5=“084637257310.1.8.34@”;
通径=0;
故障大小=0;
#定义最大地址长度32
char user_part[MAX_ADDRESS_LEN];
memset(用户\部件,0,用户\部件大小);
if(g_get_dnis_user_part(dnis_test1,user_part,MAX_ADDRESS_LEN)=TRUE){
printf(“测试1通过[%s][%s]\n”,dnis\u test1,用户部分);
通过++;
}
否则{
printf(“测试1失败[%s][%s]\n”,dnis\u test1,用户部分);
失败++;
}
memset(用户\部件,0,用户\部件大小);
if(g_get_dnis_user_part(dnis_test2,user_part,MAX_ADDRESS_LEN)=TRUE){
printf(“测试2通过[%s][%s]\n”,dnis\u测试2,用户部分);
通过++;
}
否则{
printf(“测试2失败[%s][%s]\n”,dnis\u test2,用户部分);
失败++;
}
memset(用户\部件,0,用户\部件大小);
if(g_get_dnis_user_part(dnis_test3,user_part,MAX_ADDRESS_LEN)=TRUE){
printf(“测试3通过[%s][%s]\n”,dnis_测试3,用户部分);
通过++;
}
否则{
printf(“测试3失败[%s][%s]\n”,dnis\u test3,用户部分);
失败++;
}
memset(用户\部件,0,用户\部件大小);
if(g_get_dnis_user_part(dnis_test4,user_part,MAX_ADDRESS_LEN)=TRUE){
printf(“测试4通过[%s][%s]\n”,dnis_测试4,用户部分);
通过++;
}
否则{
printf(“测试4失败[%s][%s]\n”,dnis\u test4,用户部分);
失败++;
}
memset(用户\部件,0,用户\部件大小);
if(g_get_dnis_user_part(dnis_test5,user_part,MAX_ADDRESS_LEN)=TRUE){
printf(“测试5通过[%s][%s]\n”,dnis_测试5,用户部分);
通过++;
}
否则{
printf(“测试5失败[%s][%s]\n”,dnis\u test5,用户部分);
失败++;
}
printf(“所有测试完成通过[%ld]失败[%ld]\n”,通过,失败);
返回0;
}
/*从完整的dnis编号中获取用户部件
0846372573@10.1.8.34->0846372573 nul终止*/
静态int g_get_dnis_user_part(const char*dnis,char*user_part,size\t size)
{
尺寸i=0;
int status=FALSE;
/*为nul终结者腾出空间*/
如果(大小>1){
大小--;
}
否则{
返回状态;
}
对于(i=0;i
非常感谢您的建议,不要过度优化。这是一个非常简单的函数,可以在足够小的数据集上运行,以适应缓存。很可能它已经运行得非常快了(假设优化了编译器标志,等等)。但更重要的是,这只是你整个计划的一小部分。不要花费所有的精力在汇编程序中重写这篇文章,并且仔细阅读x86体系结构手册,以确保CPU管道保持完全满的状态,或者当您确信在其他地方有更多的低挂果实时。首先评测,然后在评测器说你太慢的地方进行优化。不要过度优化。这是一个非常简单的函数,可以在足够小的数据集上运行,以适应缓存。很可能它已经运行得非常快了(假设优化了编译器标志,等等)。但更重要的是,这只是你整个计划的一小部分。不要花费所有的精力在汇编程序中重写这篇文章,并且仔细阅读x86体系结构手册,以确保CPU管道保持完全满的状态,或者当您确信在其他地方有更多的低挂果实时。首先评测,然后优化评测器显示你太慢的地方。替换
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
static int g_get_dnis_user_part(const char *dnis, char *user_part, size_t size);
int main(void)
{
/* Test cases */
const char *dnis_test1 = "0846372573@10.1.8.34";
const char *dnis_test2 = "084637257310.1.8.34";
const char *dnis_test3 = "084e672573@10.1.8.34";
const char *dnis_test4 = "";
const char *dnis_test5 = "084637257310.1.8.34@";
size_t passes = 0;
size_t failures = 0;
#define MAX_ADDRESS_LEN 32
char user_part[MAX_ADDRESS_LEN];
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test1, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 1 PASSED [ %s ] [ %s ]\n", dnis_test1, user_part);
passes++;
}
else {
printf("TEST 1 FAILED [ %s ] [ %s ]\n", dnis_test1, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test2, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 2 PASSED [ %s ] [ %s ]\n", dnis_test2, user_part);
passes++;
}
else {
printf("TEST 2 FAILED [ %s ] [ %s ]\n", dnis_test2, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test3, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 3 PASSED [ %s ] [ %s ]\n", dnis_test3, user_part);
passes++;
}
else {
printf("TEST 3 FAILED [ %s ] [ %s ]\n", dnis_test3, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test4, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 4 PASSED [ %s ] [ %s ]\n", dnis_test4, user_part);
passes++;
}
else {
printf("TEST 4 FAILED [ %s ] [ %s ]\n", dnis_test4, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test5, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 5 PASSED [ %s ] [ %s ]\n", dnis_test5, user_part);
passes++;
}
else {
printf("TEST 5 FAILED [ %s ] [ %s ]\n", dnis_test5, user_part);
failures++;
}
printf("ALL TEST COMPLETED PASSES [ %ld ] FAILURES [ %ld ]\n", passes, failures);
return 0;
}
/* Get the user part from the complete dnis number
0846372573@10.1.8.34 -> 0846372573 nul terminated */
static int g_get_dnis_user_part(const char *dnis, char *user_part, size_t size)
{
size_t i = 0;
int status = FALSE;
/* Make room for the nul terminator */
if(size > 1) {
size--;
}
else {
return status;
}
for(i = 0; i < size; i++) {
/* Check for valid digit */
if(isdigit(*dnis) != 0) {
user_part[i] = *dnis;
}
else {
if(*dnis == '@') {
/* We are at the end */
status = TRUE;
break;
}
else {
/* Not a digit or @ - corrupted dnis string */
status = FALSE;
break;
}
}
/* Next character */
dnis++;
}
/* nul terminate the string */
user_part[i++] = '\0';
/* Status FALSE indicates that the @ was not found or possible corruption with dnis string */
return status;
}
与
if(*dns>='0'&&*dns替换
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
static int g_get_dnis_user_part(const char *dnis, char *user_part, size_t size);
int main(void)
{
/* Test cases */
const char *dnis_test1 = "0846372573@10.1.8.34";
const char *dnis_test2 = "084637257310.1.8.34";
const char *dnis_test3 = "084e672573@10.1.8.34";
const char *dnis_test4 = "";
const char *dnis_test5 = "084637257310.1.8.34@";
size_t passes = 0;
size_t failures = 0;
#define MAX_ADDRESS_LEN 32
char user_part[MAX_ADDRESS_LEN];
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test1, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 1 PASSED [ %s ] [ %s ]\n", dnis_test1, user_part);
passes++;
}
else {
printf("TEST 1 FAILED [ %s ] [ %s ]\n", dnis_test1, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test2, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 2 PASSED [ %s ] [ %s ]\n", dnis_test2, user_part);
passes++;
}
else {
printf("TEST 2 FAILED [ %s ] [ %s ]\n", dnis_test2, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test3, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 3 PASSED [ %s ] [ %s ]\n", dnis_test3, user_part);
passes++;
}
else {
printf("TEST 3 FAILED [ %s ] [ %s ]\n", dnis_test3, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test4, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 4 PASSED [ %s ] [ %s ]\n", dnis_test4, user_part);
passes++;
}
else {
printf("TEST 4 FAILED [ %s ] [ %s ]\n", dnis_test4, user_part);
failures++;
}
memset(user_part, 0, sizeof user_part);
if(g_get_dnis_user_part(dnis_test5, user_part, MAX_ADDRESS_LEN) == TRUE) {
printf("TEST 5 PASSED [ %s ] [ %s ]\n", dnis_test5, user_part);
passes++;
}
else {
printf("TEST 5 FAILED [ %s ] [ %s ]\n", dnis_test5, user_part);
failures++;
}
printf("ALL TEST COMPLETED PASSES [ %ld ] FAILURES [ %ld ]\n", passes, failures);
return 0;
}
/* Get the user part from the complete dnis number
0846372573@10.1.8.34 -> 0846372573 nul terminated */
static int g_get_dnis_user_part(const char *dnis, char *user_part, size_t size)
{
size_t i = 0;
int status = FALSE;
/* Make room for the nul terminator */
if(size > 1) {
size--;
}
else {
return status;
}
for(i = 0; i < size; i++) {
/* Check for valid digit */
if(isdigit(*dnis) != 0) {
user_part[i] = *dnis;
}
else {
if(*dnis == '@') {
/* We are at the end */
status = TRUE;
break;
}
else {
/* Not a digit or @ - corrupted dnis string */
status = FALSE;
break;
}
}
/* Next character */
dnis++;
}
/* nul terminate the string */
user_part[i++] = '\0';
/* Status FALSE indicates that the @ was not found or possible corruption with dnis string */
return status;
}
与
if(*dns>='0'&&&*dns我想我应该像这样编写解析器:
if ( *dns>='0' && *dns<='9' )
static int g_get_dnis_user_part2(const char *dnis, char *user_part, size_t size)
{
if (size == 0)
return FALSE;
size_t i;
for (i=0; i<size-1 && isdigit(dnis[i]); i++)
user_part[i] = dnis[i];
user_part[i] = '\0';
return (dnis[i] == '@') ? TRUE : FALSE;
}
我试图保持它的整洁,但为了使它更快一点,请显式地(单独地)初始化,这样您就不会检查它是否初始化了每个字符(但如果使用良好的分支预测,则不会获得太多好处)
除此之外,正如其他人已经提到的,我会更改TRUE
和FALSE
的定义——您正在使用的定义让我觉得非常糟糕。按照惯例,FALSE=0和TRUE=1,并且不知道更改它们会给您带来什么有用的东西。我想我应该这样编写解析器:
if ( *dns>='0' && *dns<='9' )
static int g_get_dnis_user_part2(const char *dnis, char *user_part, size_t size)
{
if (size == 0)
return FALSE;
size_t i;
for (i=0; i<size-1 && isdigit(dnis[i]); i++)
user_part[i] = dnis[i];
user_part[i] = '\0';
return (dnis[i] == '@') ? TRUE : FALSE;
}
我试图保持它的整洁,但为了使它更快一点,请显式地(单独地)进行初始化,这样您就不会检查它是否为ini