代码优化之Base64编码函数的极限优化挑战Word文档下载推荐.docx
- 文档编号:21145685
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:39
- 大小:33.16KB
代码优化之Base64编码函数的极限优化挑战Word文档下载推荐.docx
《代码优化之Base64编码函数的极限优化挑战Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《代码优化之Base64编码函数的极限优化挑战Word文档下载推荐.docx(39页珍藏版)》请在冰豆网上搜索。
来改写;
由于拿人手段,而且以前有答应看看是否还有改进的余地;
所以空余时间
就在这个基础之上进行了一些速度优化改进尝试,本文章就是本次尝试的结果;
(声明:
本文章引用这次竞赛和其代码得到了cpper管理者的授权)
尝试了一些代码后,我在CSDN程序员网站()开贴征集最快的Base64
编码函数:
以求获得更多的思路和使已有的优化策略获得更多的验证机会;
发帖的朋友对本文章
的形成也起到了重要的作用,某些版本的函数速度得到了提高,某些在我的AMDx2
CPU上运行很快的版本、在网友的奔腾4CPU上运行减慢(放弃了一簇版本)、由讨论
而产生的新的函数版本等等;
本文章也是对这次讨论的一些简要总结(某些网友的实现
版本或策略没有整合到本文章中,请到csdn论坛直接查看);
B:
Base64编码原理简要说明
有时为了更好的传递或保存二进制数据,需要先把二进制数据转换成纯文本的编码方式。
最容易想到的方案就是直接转换成16进制的文本方式;
即把一个字节(8bit)先分成两
个4bit(值域[0..15]),然后映射到'
0'
--'
9'
'
A'
F'
这16个字符编码中;
那么一个字节
的数据转换为了两个字符,也就是说数据转换后变为原数据大小的两倍!
Base64的也能完成这个任务,但更节省空间,转换后的文本数据只是原数据大小的4/3倍;
这是怎么做到的呢?
将原数据3个字节一组(3x8bit),按一定方式分组成4个6bit(值
域[0..63]);
然后将[0..25]的值映射到'
Z'
将[26..51]的值映射到'
a'
z'
将[52..61]的值映射到'
将62的值映射为'
+'
将63的值映射为'
/'
;
由于原数据不
一定正好是3的倍数,所以分组后的4个值中有可能没有被分配bit位的情况,没有分配bit位
的值输出数据填充'
='
。
bit位分组方式示意:
//3x8bit
//|------------------|------------------|------------------|
//|
a[0..7]
|
b[0..7]
c[0..7]
//
//to4x6bit
//|------------------|------------------|------------------|------------------|
a[2..7]
|b[4..7]+a[0..1]<
<
4|c[6..7]+b[0..3]<
2|
c[0..5]
C:
一个基本实现和速度测试框架
使用了较大的数据量多次测试取平均值;
//编码函数每秒编码出的数据量:
//base64_encode0
109.0MB/s
viewplain
1.#include
time.h>
2.#include
iostream>
3.#include
vector>
4.#include
string>
5.#define
asm
__asm
6.
const
unsigned
char
BASE64_PADDING='
//输入数据不足3的倍数时
输出字符后面填充'
号
7.
8.
//将6bit数据按规则映射成字符(6bit数据)
9.
inline
to_base64char(const
code6bit)
10.
{
11.
if
(code6bit<
26)
//[
0..25]
=>
['
..'
]
12.
return
code6bit+'
13.
else
52)
//[26..51]
14.
code6bit+('
-26);
15.
62)
//[52..61]
16.
-52);
17.
(code6bit==62)
//62
18.
19.
//if
(code6bit==63)
//63
20.
21.
}
22.//编码函数(原数据地址,原数据字节大小,编码输出地址)
23.void
base64_encode0(const
void*
pdata,const
long
data_size,void*
out_pcode)
24.{
25.
char*
input=(const
char*)pdata;
26.
input_end=&
input[data_size];
27.
output=(unsigned
char*)out_pcode;
28.
for(;
input+2<
input_end;
input+=3,output+=4)
29.
30.
output[0]=to_base64char(
input[0]
>
2
);
31.
output[1]=to_base64char(
((input[0]
4)
|
(input[1]
4))
&
0x3F
32.
output[2]=to_base64char(
((input[1]
2)
(input[2]
6))
33.
output[3]=to_base64char(
input[2]
0x3F);
34.
35.
bord_width=input_end-input;
36.
(bord_width==1)
37.
38.
39.
(input[0]
40.
output[2]=BASE64_PADDING;
41.
output[3]=BASE64_PADDING;
42.
43.
(bord_width==2)
44.
45.
46.
47.
48.
49.
50.}
测试代码:
1.
typedef
void
(*Tbase64_encode_proc)(const
out_pcode);
2.
//获得编码后的输出字符大小(原数据大小)
3.
base64_code_size(const
data_size)
4.
5.
(data_size+2)/3*4;
//测试编码速度(编码器名称,编码函数,测试原数据大小)
testSpeed(const
proc_name_str,Tbase64_encode_proc
base64_encode,const
DATA_SIZE)
std:
:
cout<
"
proc_name_str<
endl;
DATA_SIZE_MAX=DATA_SIZE+12;
vector<
char>
data_buf(DATA_SIZE_MAX);
//data_buf保存需要编码的数据
for
(long
r=0;
r<
DATA_SIZE_MAX;
++r)
data_buf[r]=rand();
//data_buf填充随机数据
用以测试
code_size_MAX=base64_code_size(DATA_SIZE_MAX);
string
code_str;
//code_str用以储存编码后的字符串数据
code_str.resize(code_size_MAX,'
RunCount=0;
double
SumSpeed=0;
data_size=DATA_SIZE;
data_size<
++data_size)
22.
code_size=base64_code_size(data_size);
23.
start_time=(double)clock();
24.
base64_encode(&
data_buf[0],data_size,&
code_str[0]);
//编码测试
run_time=((double)clock()-start_time)*(1.0/CLOCKS_PER_SEC);
encode_speed=code_size*(1.0/1024/1024)/run_time;
//编码速度(MB/秒)
++RunCount;
SumSpeed+=encode_speed;
编码前数据大小(MB):
data_size*(1.0/1024/1024)<
编码速度(MB/秒):
encode_speed<
(data_size<
=1000)
code_str<
//
endl<
平均编码速度(MB/秒):
SumSpeed/RunCount<
34.}
35.int
main()
36.{
请输入任意字符开始测试(可以把进程优先级设置为“实时”)>
getchar();
DATA_SIZE=80*1024*1024;
testSpeed("
base64_encode0"
base64_encode0
DATA_SIZE);
0;
44.}
D.优化to_base64char函数
to_base64char有很多的条件分支,在当前的CPU上会严重的降低性能;
分析该函数有这样的特征:
函数的输入数据允许的取值个数很小(只能取64个值中的一个);
单个输入值对应的返回值固定;
那么我们可以建立一个数组的表格,该数组有64个元素,每个元素的值等于该元素的序
号(假定数组序号从0开始)作为to_base64char参数时的返回值;
即:
unsignedcharBASE64_CODE[64];
其中BASE64_CODE[i]=to_base64char(i);
//i属于[0..63]
那么对于这样的代码:
output[0]=to_base64char(input[0]>
2);
可以化简为:
output[0]=BASE64_CODE[input[0]>
2];
这就是利用查表来替代计算的优化方法!
(提示:
在不同的需求下,表需要灵活的构造)
base64_encode0使用查询表改进后的新代码:
//base64_encode0_table
294.6MB/s
1.const
BASE64_CODE[]=
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
3.//使用64字节的表
4.void
base64_encode0_table(const
5.{
output[0]=BASE64_CODE[
];
output[1]=BASE64_CODE[
output[2]=BASE64_CODE[
output[3]=BASE64_CODE[
0x3F];
31.}
E:
在当前的32比特CPU上一次写入4字节将获得更好的性能;
而输入数据的地方,可以先转化
成32比特整形数据再做各种复杂的位运算有利于编译器的优化(各个PC平台的差异可能比较大);
//base64_encode1
533.3MB/s
base64_addpaing(const
input,const
int
bord_width,unsigned
output)
input0=input[0];
output0=BASE64_CODE[
input0
output1=BASE64_CODE[
(input0
*(unsigned
long*)(&
output[0])=output0
(output1<
8)
((BASE64_PADDING<
16)
(BASE64_PADDING<
24));
input1=input[1];
((input0
(input1
output2=BASE64_CODE[
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 代码 优化 Base64 编码 函数 极限 挑战
![提示](https://static.bdocx.com/images/bang_tan.gif)