从我过去看到的情况来看,StackOverflow似乎喜欢编程方面的挑战,比如得到了几十个响应的快速字符到字符串运动问题。这是一个优化挑战:使用一个非常简单的函数,看看您是否能够想出一种更聪明的方法来实现它。
我有一个函数,我想要进一步优化很长一段时间,但我总是发现,我的优化有一些漏洞,导致不正确的输出-一些罕见的特殊情况下,他们失败。但是,考虑到这一功能,我一直认为人们应该能够做得更好。
该函数接受输入数据from (从熵的角度来看实际上是随机比特),并将其封装到NAL单元中。这包括放置转义码:任何字节序列00 00、00 01、00 00 02或00 00 03被替换为00 03 XX,其中XX是原始序列的最后一个字节。可以猜到,考虑到这样一个序列的概率,每输入400万字节,这些数据只占1的位置--所以这是一个挑战,一个人正在搜索大量的数据,几乎什么都不做--除了非常罕见的情况下,几乎什么都不做。但是,因为“做某事”需要插入字节,所以这会使事情变得更加棘手。当前未优化的代码是以下C:
src和dst是指向字节数组的指针,end是指向输入数据末尾的指针。
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字节之间。
我最初的想法包括一个函数,它(以某种方式)在输入中快速搜索需要转义代码的情况,以避免在大多数不需要放置转义代码的输入中出现更复杂的逻辑。
发布于 2008-09-29 04:21:34
Hmm...how关于这样的事情?
#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之间有一些重复的工作,但是最好摆脱掉。
发布于 2008-09-29 03:35:50
将明显的优化应用于代码:
#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;
}发布于 2008-09-29 04:07:09
迈克·F,非常感谢你提出的“不可能”的建议:下面的建议比原来的大约快了10%:
#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又怪怪的了。
#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++;
}然而,我希望的不仅仅是优化当前的天真方法;我怀疑一定有更好的方法来做到这一点,而不仅仅是单独处理每个字节。
https://stackoverflow.com/questions/147408
复制相似问题