首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >性能挑战: NAL单位包装

性能挑战: NAL单位包装
EN

Stack Overflow用户
提问于 2008-09-29 03:30:14
回答 7查看 922关注 0票数 3

从我过去看到的情况来看,StackOverflow似乎喜欢编程方面的挑战,比如得到了几十个响应的快速字符到字符串运动问题。这是一个优化挑战:使用一个非常简单的函数,看看您是否能够想出一种更聪明的方法来实现它。

我有一个函数,我想要进一步优化很长一段时间,但我总是发现,我的优化有一些漏洞,导致不正确的输出-一些罕见的特殊情况下,他们失败。但是,考虑到这一功能,我一直认为人们应该能够做得更好。

该函数接受输入数据from (从熵的角度来看实际上是随机比特),并将其封装到NAL单元中。这包括放置转义码:任何字节序列00 00、00 01、00 00 02或00 00 03被替换为00 03 XX,其中XX是原始序列的最后一个字节。可以猜到,考虑到这样一个序列的概率,每输入400万字节,这些数据只占1的位置--所以这是一个挑战,一个人正在搜索大量的数据,几乎什么都不做--除了非常罕见的情况下,几乎什么都不做。但是,因为“做某事”需要插入字节,所以这会使事情变得更加棘手。当前未优化的代码是以下C:

src和dst是指向字节数组的指针,end是指向输入数据末尾的指针。

代码语言:javascript
复制
int i_count = 0;
while( src < end )
{
    if( i_count == 2 && *src <= 0x03 )
    {
        *dst++ = 0x03;
        i_count = 0;
    }
    if( *src == 0 )
        i_count++;
    else
        i_count = 0;
    *dst++ = *src++;
}

此函数的通用输入大小大约在1000到1000000字节之间。

我最初的想法包括一个函数,它(以某种方式)在输入中快速搜索需要转义代码的情况,以避免在大多数不需要放置转义代码的输入中出现更复杂的逻辑。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2008-09-29 04:21:34

Hmm...how关于这样的事情?

代码语言:javascript
复制
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)

while( likely(src < end) )
{
    //Copy non-zero run
    int runlen = strlen( src );
    if( unlikely(src+runlen >= end) )
    {
        memcpy( dest, src, end-src );
        dest += end-src;
        src = end;
        break;
    }

    memcpy( dest, src, runlen );
    src += runlen;
    dest += runlen;

    //Deal with 0 byte
    if( unlikely(src[1]==0 && src[2]<=3 && src<=end-3) )
    {
        *dest++ = 0;
        *dest++ = 0;
        *dest++ = 3;
        *dest++ = *src++;
    }
    else
    {
        *dest++ = 0;
        src++;
    }
}

在strcpy和memcpy之间有一些重复的工作,但是最好摆脱掉。

票数 4
EN

Stack Overflow用户

发布于 2008-09-29 03:35:50

将明显的优化应用于代码:

代码语言:javascript
复制
#define unlikely(x) __builtin_expect((x),0)

while( src < end )
{
    const char s = *src++;
    if( unlikely(i_count==2 && s<=0x03) )
    {
        *dst++ = 0x03;
        i_count = 0;
    }
    if( unlikely(s==0) )
        i_count++;
    else
        i_count = 0;
    *dst++ = s;
}
票数 1
EN

Stack Overflow用户

发布于 2008-09-29 04:07:09

迈克·F,非常感谢你提出的“不可能”的建议:下面的建议比原来的大约快了10%:

代码语言:javascript
复制
#define unlikely(x) __builtin_expect((x),0)
while( src < end )
{
    if( unlikely(i_count == 2) && unlikely(*src <= 0x03) )
    {
        *dst++ = 0x03;
        i_count = 0;
    }
    if( unlikely(*src == 0) )
        i_count++;
    else
        i_count = 0;
    *dst++ = *src++;
}

而且,更好的是,下面的速度比原来的快了50% (!!)我还是不明白为什么循环条件中的可能()会有帮助.一定是gcc又怪怪的了。

代码语言:javascript
复制
#define unlikely(x) __builtin_expect((x),0)
#define likely(x) __builtin_expect((x),1)
while( likely(src < end) )
{
    if( unlikely(i_count == 2) && unlikely(*src <= 0x03) )
    {
        *dst++ = 0x03;
        i_count = 0;
    }
    if( unlikely(*src == 0) )
        i_count++;
    else
        i_count = 0;
    *dst++ = *src++;
}

然而,我希望的不仅仅是优化当前的天真方法;我怀疑一定有更好的方法来做到这一点,而不仅仅是单独处理每个字节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/147408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档