background image

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 使用一个字节来描述的要求。