优化语法分析器函数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