首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

千分求最快的Base64编码函数解决方案

2012-02-04 
千分求最快的Base64编码函数千分求最快的Base64编码函数我有上万的可用分,可以开新贴给分Base64编码是很常

千分求最快的Base64编码函数
千分求最快的Base64编码函数

我有上万的可用分,可以开新贴给分

Base64编码是很常用的一种把二进制数据转换为字符串的算法;
  (它把3个8bit数据分成4组6bit数据,然后拿6bit数映射到64个可显示字符集合中的一个)

我开贴征集最快的Base64编码函数,要求如下:
    1.使用200MB随机数据来测试编码函数         (数据量最少的话也要20MB上)
    2.测试单位时间(秒)编码出的字符数据量     (假设200MB数据用了2秒钟编码时间,那速度就是:200MB/3*4/2s=133.3MB/s)
    3.必须说明测试使用的CPU型号(运行频率)、最好说明内存型号(运行频率)   、语言和编译器类型
    4.可以测试已有的Base64编码函数(比如各种库中的、开源的等等),注明来源(可以不提供源代码),也可以是自己写的(最好能给出源代码)
    5.可以补充测试一下Base64解码函数的速度
    (如果是自己写的   看函数速度   给分时酌情加分)


==========================================================================
//testBase64.cpp
//一个简单的base64_encode编码函数例子,和测试框架
#include   <time.h>
#include   <iostream>
#include   <vector>
#include   <string>

    //   3x8bit   to   4x6bit
    //   |----------------------|----------------------|----------------------|
    //   |                 a[0..7]               |               b[0..7]                 |               c[0..7]                 |
    //   |----------------------|----------------------|----------------------|
    //
    //   |----------------------|----------------------|----------------------|----------------------|
    //   |                 a[2..7]               |   b[4..7]   +   a[0..1] < <4   |   c[6..7]   +   b[0..3] < <2   |               c[0..5]                 |
    //   |----------------------|----------------------|----------------------|----------------------|

const   unsigned   char   BASE64_PADDING= '= ';     //输入数据不足3的倍数时   输出字符后面填充 '= '号


        inline   unsigned   char   to_base64char(const   unsigned   char   code6bit)
        {
                if   (code6bit <26)                   //[   0..25]   =>   [ 'A '.. 'Z ']
                        return   code6bit+ 'A ';
                else   if   (code6bit <52)         //[26..51]   =>   [ 'a '.. 'z ']
                        return   code6bit+( 'a '-26);
                else   if   (code6bit <62)         //[52..61]   =>   [ '0 '.. '9 ']
                        return   code6bit+( '0 '-52);
                else   if   (code6bit==62)       //62   =>   '+ '
                        return   '+ ';


                else   //if   (code6bit==63)   //63   =>   '/ '
                        return   '/ ';
        }

void   base64_encode(const   void*   pdata,const   unsigned   long   data_size,void*   out_pcode)
{
if   (data_size <=0)   return;
        const   unsigned   char*   input=(const   unsigned   char*)pdata;
        const   unsigned   char*   input_end=&input[data_size];
        unsigned   char*               output=(unsigned   char*)out_pcode;

        const   unsigned   char*   input_end_sub_2=input_end-2;
for(;input <input_end_sub_2;input+=3,output+=4)
{
output[0]=to_base64char(input[0]/4);
output[1]=to_base64char(input[0]%4*16   +   input[1]/16);
output[2]=to_base64char(input[1]%16*4   +   input[2]/64);
output[3]=to_base64char(input[2]%64);
}

        unsigned   long   bord_width=input_end-input;
        if   (bord_width==1)
        {
output[0]=to_base64char(input[0]/4);
output[1]=to_base64char(input[0]%4*16);
output[2]=BASE64_PADDING;
output[3]=BASE64_PADDING;
        }
        else   if   (bord_width==2)
        {
output[0]=to_base64char(input[0]/4);
output[1]=to_base64char(input[0]%4*16   +   input[1]/16);
output[2]=to_base64char(input[1]%16*4);
output[3]=BASE64_PADDING;
        }
}


typedef   void   (*Tbase64_encode_proc)(const   void*   pdata,const   unsigned   long   data_size,void*   out_pcode);

        inline   unsigned   long   base64_code_size(const   unsigned   long   data_size)
        {
                return   (data_size+2)/3*4;
        }


  void   testSpeed(const   char*   proc_name_str,Tbase64_encode_proc   base64_encode,const   long   DATA_SIZE)
  {
        std::cout < < "> >   编码函数:   " < <proc_name_str < <std::endl;

        const   long   DATA_SIZE_MAX=DATA_SIZE+12;  

        std::vector <unsigned   char>   data_buf(DATA_SIZE_MAX);   //data_buf保存需要编码的数据
        for   (long   r=0;r <DATA_SIZE_MAX;++r)  
                data_buf[r]=rand();   //data_buf填充随机数据   用以测试

        const   long   code_size_MAX=base64_code_size(DATA_SIZE_MAX);
        std::string   code_str;//code_str用以储存编码后的字符串数据
        code_str.resize(code_size_MAX, '   ');

        long       RunCount=0;
        double   SumSpeed=0;
        for   (long   data_size=DATA_SIZE;data_size <DATA_SIZE_MAX;++data_size)
        {  



const   long   code_size=base64_code_size(data_size);
        double   start_time=(double)clock();

        base64_encode(&data_buf[0],data_size,&code_str[0]);//编码测试

        double   run_time=((double)clock()-start_time)*(1.0/CLOCKS_PER_SEC);

                double   encode_speed=code_size*(1.0/1024/1024)/run_time;//编码速度(MB/秒)
                ++RunCount;
                SumSpeed+=encode_speed;

                std::cout < < "   编码前数据大小(MB):   " < <data_size*(1.0/1024/1024) < < "       编码速度(MB/秒):   " < <encode_speed < <std::endl;
                //if   (data_size <=1000)   std::cout < <code_str < <std::endl;   //
        }
        std::cout < <std::endl < < "         平均编码速度(MB/秒):   " < <SumSpeed/RunCount < <std::endl;
        std::cout < <std::endl;

  }

int   main()
{
std::cout < < "   请输入任意字符开始测试(可以把进程优先级设置为“实时”)>   ";
getchar();
std::cout < <std::endl;

const   long   DATA_SIZE=80*1024*1024;

testSpeed( "base64_encode "           ,base64_encode           ,DATA_SIZE);
return   0;
}
===========================================================================


例子的结果说明:
      1.测试数据集80MB
      2.base64_encode编码函数速度(进程为 "实时 "优先级):   90.8MB/s
      3.CPU:   AMD64x2   3600+(2.01G);   内存:   DDR2   667(334.9MHz);   语言:C++;   编译器:VC2005

[解决办法]
随手C写了个, 在 PM1.4G 上对200M数据编码, 速度是 183 M/sec ... 偶想在偶的破机器上, 优化到400M/sec应该是很有希望的 ...
[解决办法]
我在赛扬2.1G DDR333上测试
不惑的代码跟lz的新代码基本都是一样的速度。平均基本都是接近370M/s
可能不惑的还要好一点点 5次:371 369 371 372 369
Lz的5次:370 370 369 368 370
base64_from_delphi_VCL函数新的反而不如旧的,新的只有268.5,旧的可以达到307.6
上面结果都在BCB6中测试。
base64_encode_asm:没通过,程序自动退出,D7中
[解决办法]
发错了,这才是Encode

procedure IntBase64Encode(PStr1, PStr2: Pointer; Len: Integer);
asm
PUSH EBX
PUSH ESI
PUSH EDI
MOV EBX,EAX
MOV ESI,ECX
MOV EDI,EDX
@@lp: SUB ESI,3
JS @@nx
XOR EAX,EAX
MOV AH,BYTE PTR [EBX]
MOV AL,BYTE PTR [EBX+1]
MOVZX EDX,BYTE PTR [EBX+2]
SHL EAX,8
OR EAX,EDX
ROL EAX,14
MOVZX EDX,AL
AND EAX,$FFFFFF00
ROL EAX,6
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI],CL
MOVZX EDX,AL
AND EAX,$FFFF0000
ROL EAX,6
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+1],CL
MOVZX EDX,AL
AND EAX,$FF000000
ROL EAX,6


MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+2],CL
MOVZX EDX,AL
ADD EBX,3
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+3],CL
ADD EDI,4
JMP @@lp
@@nx: ADD ESI,3
JMP DWORD PTR @@tV[ESI*4]
@@tV: DD @@tu0,@@tu1,@@tu2
@@tu0: POP EDI
POP ESI
POP EBX
RET
@@tu1: XOR EAX,EAX
MOV AL,BYTE PTR [EBX]
ROR EAX,2
MOVZX EDX,AL
AND EAX,$FFFFFF00
ROL EAX,6
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI],CL
MOVZX EDX,AL
MOV BYTE PTR [EDI+2],61
MOV BYTE PTR [EDI+3],61
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+1],CL
POP EDI
POP ESI
POP EBX
RET
@@tu2: XOR EAX,EAX
MOV AH,BYTE PTR [EBX]
MOV AL,BYTE PTR [EBX+1]
ROR EAX,10
MOVZX EDX,AL
AND EAX,$FFFFFF00
ROL EAX,6
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI],CL
MOVZX EDX,AL
AND EAX,$FFFF0000
ROL EAX,6
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+1],CL
MOVZX EDX,AL
MOV BYTE PTR [EDI+3],61
MOV CL,BYTE PTR [EDX+Base64Chars]
MOV BYTE PTR [EDI+2],CL
POP EDI
POP ESI
POP EBX
end;

热点排行