3
this
.WriteString(value.ToString(CultureInfo.InvariantCulture));
4
}
通常情况下
,一列的数据都是很小的数字,例如数量或者单价,可能 0,也可能正整数,也可能
是
0.17 这样的小数.根据
WriteString
的实现可知,需要至少一个字节描述字符串的长度,然
后一个字符占用一个字节(默认
utf8),也就是说,数字 0 占用 2 个字节,0.17 占用 5 个字
节。
还不错啊,至少比
16 个字节好多了。
有没有更好的压缩
观察
我对微软的实现还不够满意,仔细观察常见的数据,可以总结道:
1、 通常一个小数由整数部分、小数部分和小数位数组成,例如 0.17 整数是 0,小数部分是
17,小数位数是 2,另外一个例子 1.007,整数部分是 1,小数部分是 7,小数位数是 3;
2、 如果小数位数是 0,即整数,那么就不必描述小数部分了;
3、 如果数字就是 0,这种情况非常多,是不是用 1 个字节而不是 2 个字节描述呢?
4、 像 17 这样的数字,用字符串描述就需要 2 个字节,而如果用二进制,1 个字节就够了。
基本方法
所以我的方法是:第一个字节描述小数位数,后面的字节描述整数部分,如果小数位数大
于
0,则还包含小数部分的整数描述。
例如
0.12,我会存储 2,0,12 三个正整数,十六进制描述就是
02
00
0C
我在上面多处提到正整数,我们可以利用
7BitEncodedInt
方式填写整数部分和小数部分,
他是一种可变长的描述方法。
如果数字是整数,我们还可以省略小数部分,例如
12
00
0C
到这里,我们发现一个问题,如果是数字
0,第一个字节和上面是一样的(为 0),这样即
使
0 也还需要再存储一个字节 0,用来确定整数部分是 0,不然读取时,就无法区分 0 和 12
了,但这就达不到我之前提到的数字
0 使用一个字节来描述的要求。