数据存储优化思路扩展

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
下面是几个数据存储优化的例子, 也是常见的几个例子,都挺有意思。
可能例子的适用性是有一定限制的, 不过例子汇聚到一起,从数据存储优化思路来分析,还是挺有益处的:

1. 交换两个数字,不使用新增变量和函数

(参考实现代码,仅代表一种实现思路)

void swap(int &a, int &b){
    a = a + b;
    b = a - b;
    a = a - b;
};

这个算法是:
基于数据与求和数据的关联,完成了数据交换。
a =(a+b)-b;
b =(a+b)-a;
适用性上:
适用于两个值相加不溢出的情况;

2. 返回两个中的最大的,不使用条件分支与函数

(参考实现代码,仅代表一种实现思路)

int max(int a, int b){
    int sum = a + b;
    int sub = a - b;
    unsigned int flag = (0x80000000 & (unsigned int)sub) >> 31;
    sub = ((-flag) ^ (unsigned int)sub) + flag;
    sum += sub;
    return sum / 2;
};

这个算法是:基于几个个特点
a. 求和数据与求差数据的关联 (a+b) + |a-b| = 2max(a, b)

b. int数据存储结构上,最高位是符号位,可以取出该符号位用于计算

c. 异或操作:与0异或得到其本身,与1异或取反

d. 正负数互转时时,采用取反+1

3. 基于数据自身取值范围的优化存储

例如图片的大小取值一般都是由大小范围限制的;
可以基于它的范围限制特点,优化存储空间。
如果图片大小取值范围在(0, 65536]范围内,前开后闭:就可以把长宽两个取值压缩到一个4字节(32bit)范围内;

   压缩时:
   int height = width = 65536; 
   unsigned int merge = (width - 1) << 16 + (height - 1);
   
   解压时:
   int height = merge & 0xFFFF + 1;
   int width = (merge >> 16) & 0xFFFF + 1;

当然如果图片大小取之范围(0, 1024]范围的:
可以用更小的空间来压缩width/height;
20bit就可以完成两个值得存储。

4. 无符号数基于取值的7位压缩有效值压缩

在自然界通常碰到的整数数字都不是很大,只有少量的较大数字,但是选用4字节存储的范围却很大。
从二进制上来看,大多数字,高位很多0,第一个有效位1产生的比较靠后,从第一个出现的1开始,可能只有较短的长度就结束了。如果能只存储这较短的有效长度,就可以省掉前面高位取值0的空间。
希望算法可以同时满足大数字与小数字的存储,又能基于数字的范围占用不同的空间大小,7位有效值法就非常适用了。
一个字节8位,使用1位来标示,是否数字存储结束;
首位:
0-标示存储值结束
1-标示还有后续字节存值;

其余7位:
存储数值;

这样解析值的时候,就可以一个字节一个字节读取,发现高位为0时结束;把有效数值位串起来就是数字的值。

从而<2^7=128时,1个字节就存下了;
从而<2^14=16384时,2个字节就存下了;

5. ZIGZAG负数优化取值

zigzag负数优化取值的原理是,负数通常会在高位占有较多的带1的值,如果对有效位存储的话,例如上面的7位存值的方式—可以把高位的0占用空间都节省掉:但负数的话却不适用,最高位是1,7位存值方式—通常要存更多字节才能保存完。
那为什么不能把负数映射到正数的区间中,把符号位往后放,这样来大多数出现的负数高位取0的值比较多,来节省空间呢?
zigzag的算法就应运而生了。

zigzag-encode时把符号位存到最后1位:
对于负数时,把取值部分存反码在其余位上。
对于正数时,把取之部分直接放在其余位上。
zigzag-decode时,做逆操作;

经过zigzag处理后,对于负值,在用类似7位存值优化方法,大多数情况下就比较能够节省空间了。
abs(value) < 2^6=64时,1个字节存储(负值时,多存一个-64)
abs(value) < 2^13=8192时,2个字节存储(负值时,多存一个-8192)

6. 其它思路

利用数据优化存储的思路还有许多,甚至还包括压缩算法的一些思路,都可以完成数据的存储优化

a. 像是圆属性中的面积与半径,可以互相推倒, 保留其一即可

b. 像是利用单位向量的单位化特点,可以从x/y分量得出z分量

c. 像是把数字从文本形态转到二进制存储,数据格式的变更

d. 像是hex码改用base64压缩后,即能够保留原来可见的特点,又可以节省约1/3的空间

e. 像是为了网络传输,常把文件gzip压缩之后,传输给浏览器,浏览器解压后呈现

等等…

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春夜喜雨

稀罕你的喜欢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值