java 开发使用字符串和数字的性能分析

java 开发使用字符串和数字的性能分析

前言:

分析使用字符串和数字,在软件产品上线后用户较多的情况下,很有必要考虑的问题,这直接体现了用户的体验程度,总不能让用户用着很卡的感觉吧!

在我多年的开发经验中,经常发现的一个情况就是,很多项目的对象字段或者是数据库字段本来是数字类型的,却被定义成字符串类型,这无关痛痒吗?

对于小项目来说,可能没什么影响,反正只要业务逻辑正确即可,性能没什么问题,因为数据也不多,用户也不多。

然而,对于大数据处理来说,这个可不是小事,从字符串替换为数字类型,可以极大地节省内存、磁盘存储以及网络带宽,减少IO的代价,而且很多数据结构和算法使用数字类型比字符串要更快。

我们来看一个例子,假设你有很多的日志需要处理,而每条日志都有一个唯一的标识,标识类似这样的格式:

F5051582611729507844
3832154813577306424
F1624235934976711017
3810376634214027595
F6884923813121317381
7278044081826528150

看到这些标识,你怎么想?我的第一反应应该是数字,可是怎么有个F呢?我想可以把它当做16进制。后来发现可以把F当做负号,这就是一个64位的长整型。

那么如果你把这些标识当成字符串,会有什么不同呢?

当然有,如果你每秒要处理这样的日志百万或者千万条,每条处理结果可能会包含百万或者千万个这样的标识元素构成的集合,这个不同就会体现的非常明显。

下面,我们来分析一下标识3832154813577306424的存储占用情况:

1、内存占用

当做字符串:我们知道,JAVA中字符串是由字符构成的,一个字符是由2个字节构成的(这是JAVA的悲剧了),上述标识有19个字符,所以,占用的内存大小为:19*2+4=42(字节),+4是因为字符串使用一个整型保存字符串的哈希值。

当做数字:如当做长整型,则占用的内存大小为8字节。

这里有5倍以上的差距了吧。

2、序列化字节大小

当我们需要通过网络传输这些标识或者需要把这些标识存储到磁盘中的时候,我们就需要把这些标识转换为字节数组,如何转换为字节数组呢?我们可以使用多种编码方式。

当做字符串:我们知道,JAVA中字符串转换为字节数组可以使用多种编码方式,我们看看常见的编码方式对如上字符串编码之后的字节数:

String abc = "3832154813577306424";

System.out.println("3832154813577306424 length:"+abc.length());
System.out.println(Charset.defaultCharset().name()+":"+abc.getBytes().length);
System.out.println("unicode:"+abc.getBytes("unicode").length);
System.out.println("gbk:"+abc.getBytes("gbk").length);
System.out.println("gb2312:"+abc.getBytes("gb2312").length);
System.out.println("ISO-8859-1:"+abc.getBytes("ISO-8859-1").length);

输出如下:

3832154813577306424 length:19
UTF-8:19
unicode:40
gbk:19
gb2312:19
ISO-8859-1:19

当做数字:如当做长整型,则占用的内存大小为8字节。

这里有2倍以上的差距了吧。

那么我们如何在长整型和字节数组之间转换呢?

String abc = "3832154813577306424";

System.out.println("3832154813577306424 length:"+abc.length());
System.out.println("long:"+ByteUtils.longToBytes(Long.parseLong(abc)).length);
byte[] bytes = ByteUtils.longToBytes(Long.parseLong(abc));
System.out.println("string:"+ByteUtils.bytesToLong(bytes));

输出如下:

3832154813577306424 length:19
long:8
string:3832154813577306424
public static byte[] longToBytes(long x) {
  ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);
  longBuffer.putLong(0, x);
  return longBuffer.array();
}
public static long bytesToLong(byte[] bytes) {
  return bytesToLong(bytes, 0, bytes.length);
}
public static long bytesToLong(byte[] bytes, int offset, int length) {
  ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);
  longBuffer.put(bytes, offset, length);
  longBuffer.flip();//need flip
  return longBuffer.getLong();
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java 开发使用字符串和数字的性能分析

    java 开发使用字符串和数字的性能分析 前言: 分析使用字符串和数字,在软件产品上线后用户较多的情况下,很有必要考虑的问题,这直接体现了用户的体验程度,总不能让用户用着很卡的感觉吧! 在我多年的开发经验中,经常发现的一个情况就是,很多项目的对象字段或者是数据库字段本来是数字类型的,却被定义成字符串类型,这无关痛痒吗? 对于小项目来说,可能没什么影响,反正只要业务逻辑正确即可,性能没什么问题,因为数据也不多,用户也不多. 然而,对于大数据处理来说,这个可不是小事,从字符串替换为数字类型,可以极大

  • JAVA LinkedList和ArrayList的使用及性能分析

    第1部分 List概括List的框架图List 是一个接口,它继承于Collection的接口.它代表着有序的队列.AbstractList 是一个抽象类,它继承于AbstractCollection.AbstractList实现List接口中除size().get(int location)之外的函数.AbstractSequentialList 是一个抽象类,它继承于AbstractList.AbstractSequentialList 实现了"链表中,根据index索引值操作链表的全部函数

  • Java通过正则表达式获取字符串中数字的方法示例

    前言 本文通过一个小范例来学习java中通过正则表达式如何获得一个字符串中的数字,下面话不多说,来看看详细的介绍吧. 示例代码如下: import java.util.regex.Matcher; import java.util.regex.Pattern; public class test { public static void main(String[] args) { String strInput = "3a7s10@5d2a6s17s56;33"; String reg

  • Java中关于控制台读取数字或字符串的方法

    Java中,int a = System.in.read();此句读取的是一个字符,然后返回的是对应字符的ASCII, 例如,控制台输入123,只读取一个字符1,对应的ASCII为49,则输出49,输入abc则读取a,对应的ASCII是97,则输出97: Scanner sc = new Scanner(System.in) int n = sc.nextInt();从控制台读取一个数. String c = sc.next();//从控制台读取字符串 以上就是小编为大家带来的Java中关于控制

  • 关于java开发的性能问题总结(必看)

    1:hibernate的hql如何处理分表问题?如果不能处理,hibernate是不是比mybatis的扩展性差,灵活性差. 2:where in()效率真的很低吗? 3:spring事物配置,如何配置子事物的异常不会让主事物回滚? 4:数据库做删除操作,会影响查询吗?锁获取异常在每天2万数据量的情况下,真的会经常出现. 以上这篇关于java开发的性能问题总结(必看)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Java简单统计字符串中汉字,英文字母及数字数量的方法

    本文实例讲述了Java简单统计字符串中汉字,英文字母及数字数量的方法.分享给大家供大家参考,具体如下: package org.zhy.demo.algorithm; /** * 有一个字符串,其中包含中文字符.英文字符和数字字符,请统计和打印出各个字符的个数 * * @author Administrator * */ public class Str { public static void main(String[] args) { String str = "adasfAAADFD阿萨德

  • Java中Boolean与字符串或者数字1和0的转换实例

    mysql有个字段是bit,只存储1和0,是二进制存储,那么在java的dao层如何映射成boolean呢 @Column(name="is_standard") private boolean isStandard; public void setIsStandard(boolean isStandard){ this.isStandard = isStandard; } public boolean getIsStandard(){ return isStandard; } 其实就

  • Java实现从字符串中找出数字字符串的方法小结

    本文实例总结了Java实现从字符串中找出数字字符串的方法.分享给大家供大家参考,具体如下: int start = 0; String numStr = null; for (int j = 0; j < valuesStr.length() - 1; j++) { if (Character.isDigit(valuesStr.charAt(j)) == false && Character.isDigit(valuesStr.charAt(j + 1)) == true) { s

  • java实现统计字符串中大写字母,小写字母及数字出现次数的方法示例

    本文实例讲述了java实现统计字符串中大写字母,小写字母及数字出现次数的方法.分享给大家供大家参考,具体如下: public class TestSubstring { public static void main(String[] args) { getCount("adsJKJ3K21AfaAD134F13241d134134s141faAAFDF"); } //统计字符串中,大写字母,小写字母,数字出现的次数 public static void getCount(String

  • java实现字符串和数字转换工具

    本文实例为大家分享了java字符串和数字转换工具的具体代码,供大家参考,具体内容如下 package com.test.util; /** * 数字工具类 */ public class NumberUtil { /** * 数字转换为字符串 * @param num 数字 * @return 字符串,如果 num 为空, 返回空字符串 */ public static String num2Str(Object num) { String str = null; if (num == null

随机推荐