java中的double vs long序列化

时间:2012-10-02 22:03:56

标签: java performance serialization deserialization hbase

我可以将一个数字存储为HBase中的Long和Double。它们都在Java中占用8个字节。

使用Double的优点在于它为存储整数提供了更广泛的范围。

然而,我认为Long的范围也足以供我使用。

有没有人对Long vs Dobule的序列化和反序列化性能有任何想法?我对它们之间的比较感兴趣。

感谢。

3 个答案:

答案 0 :(得分:18)

如果要存储整数,请使用Long。您声明“使用Double的优点是它为存储整数提供了更广泛的范围”是不正确的。两者都是64位长,但double必须使用一些位作为指数,留下更少的位来表示幅度。您可以在double中存储较大的数字,但会丢失精确度。

换句话说,对于大于某个上限的数字,您不能再存储相邻的“整数”...如果给定一个高于此阈值的整数值,则“下一个”可能的double将大于1大于前一个数字。

例如

public class Test1  
{

    public static void main(String[] args) throws Exception 
    {
        long   long1 = Long.MAX_VALUE - 100L;
        double dbl1  = long1;
        long   long2 = long1+1;
        double dbl2  = dbl1+1;
        double dbl3  = dbl2+Math.ulp(dbl2);

        System.out.printf("%d %d\n%f %f %f", long1, long2, dbl1, dbl2, dbl3);
    }

}

输出:

9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000

请注意

  1. Long.MAX_VALUE-100的双重表示 NOT 等于原始值
  2. 在Long.MAX_VALUE-100的双重表示中添加1无效
  3. 在这个幅度上,一个双倍和下一个可能的双重值之间的差异是2000。
  4. 另一种说法是long精度不到19位,而double精度只有16位。 Double可以存储大于16位的数字,但代价是以低位数字截断/舍入。

    如果您需要超过19位数的精确度,您必须使用BigInteger,预期性能会下降。

答案 1 :(得分:3)

这看起来像是错误的战斗:

来自Java Tutorial

  

长数据类型是64位带符号的二进制补码整数。它有   最小值为-9,223,372,036,854,775,808,最大值为   9,223,372,036,854,775,807(含)。

这非常接近19位有效数字

来自Wikipedia

  

这给出了15到17个有效小数位数。

所以,尽管它有明显的“优势”,Double会让你比Long更糟糕。我只是在这里猜测,但直观地说,我认为浮点类型的序列化/反序列化比对整数数据类型的相同操作更昂贵,但即使存在差异,它们在现代系统上也会非常小。

因此,在使用整数时,请坚持使用Long。

答案 2 :(得分:1)

在没有具体了解的情况下,我会想象longdouble都具有相同的序列化:取64位并将它们放在线上。同样地,我认为反序列化只需要从线路上取64位,并声明它们现在代表longdouble。任何64位都将代表有效的longdouble(虽然并非所有都代表有限的双倍),因此没有任何验证或额外的工作。