开发实战细节之——关于整型转换为字符串类型的性能与实现分析

细节决定成败,开发中往往从一些细节就可以看出一个程序员的开发水准,下面我就给大家分享一下开发中最最常见的int转换为String类型的方法及其性能解析。

一般大家最常用的方法有

方法一:String s1 = String.valueOf(i); 

方法二:String s2 = i+"";  

不知道有没有人用这种方法呢?

方法三:String s3 = Integer.toString(i);

继续往下看之前,大家先猜测一下这三种方法哪种方法的效率最高,耗时最短,对内存消耗最小?相信结果会令你大吃一惊!

话不多说,直接上代码,用事实说话。

package com.zhu.test;public class IntToStringOptimize {public static void main(String[] args) {//1.String.valueOf(i)方式long t = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {String s0 = String.valueOf(i);}System.out.println("String.valueOf(i)方式耗时:" + (System.currentTimeMillis() - t));//2.i+""方式t = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {String s = "" + i;}System.out.println("i+ \"\" 方式耗时       :" + (System.currentTimeMillis() - t));//3.Integer.toString(i)方式t = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {String s = Integer.toString(i);}System.out.println("Integer.toString(i)方式耗时:" + (System.currentTimeMillis() - t));}
}

 

运行结果如下:

结果是不是大跌眼镜啊?没想到我们最常用的i+""的性能竟然如此之差!而性能最好的竟然是没人怎么用的toString(i);为什么会这样呢?经过堆栈分析发现:

String.valueOf(i)的方法调用的竟然时第三种方法:Integer.toString(i),多此调试后发现他们的耗时比基本保持在20:8,那么toString(i)的内部又是怎样实现的呢?

下面是Integer.toString(i)的实现代码:

1 public static String toString(int i) {
2                 if (i == Integer.MIN_VALUE)
3                     return "-2147483648";
4                 int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
5                 char[] buf = new char[size];
6                 getChars(i, size, buf);
7                 return new String(buf, true);
8             }

其中stringSize(i)又做了什么事呢?经过进一步跟踪发现

1  static int stringSize(int x) {
2                 for (int i=0; ; i++)
3                     if (x <= sizeTable[i])
4                     return i+1;
5               }

而sizeTable[]又是一个怎样的数组呢?继续往下看,

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999, Integer.MAX_VALUE };

原来在调用toString(i)的时候,如果会判断i是否是负数,如果是负数就将其求反为正数,然后会根据 sizeTable数组来 判断 i 的位数并返回创建一个比i的长度+1的字符数组,比如i=11,那么size就是3,然后就会创建一个3位的字符数组。那么问题来了,getChars()有是干什么的呢?

 1  /**
 2      * Places characters representing the integer i into the
 3      * character array buf. The characters are placed into
 4      * the buffer backwards starting with the least significant
 5      * digit at the specified index (exclusive), and working
 6      * backwards from there.
 7      *
 8      * Will fail if i == Integer.MIN_VALUE
 9      */
10     static void getChars(int i, int index, char[] buf) {
11         int q, r;
12         int charPos = index;
13         char sign = 0;
14 
15         if (i < 0) {
16             sign = '-';
17             i = -i;
18         }
19 
20         // Generate two digits per iteration
21         while (i >= 65536) {
22             q = i / 100;
23          
24             r = i - ((q << 6) + (q << 5) + (q << 2));
25             i = q;
26             buf [--charPos] = DigitOnes[r];
27             buf [--charPos] = DigitTens[r];
28         }
29 
30         // Fall thru to fast mode for smaller numbers
31         // assert(i <= 65536, i);
32         for (;;) {
33             q = (i * 52429) >>> (16+3);
34             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
35             buf [--charPos] = digits [r];
36             i = q;
37             if (i == 0) break;
38         }
39         if (sign != 0) {
40             buf [--charPos] = sign;
41         }
42     }

仔细分析代码发现,这个函数的功能就是将int型的i从右向左(即从个位数开始)填充到字符数组buf中。至此方法一String.valueOf(i)和方法三Integer.toString(i)分析完毕。

由上可见,方式二 i+"" 是最耗时耗内存的方法,之所以写这篇文章是因为我在看一段视频的时候以为老师说他以前刚入职的时候就是用这种方法从而项目中出现大量的+"",结果是被项目经理批评了一顿。所以小伙伴们,如果你还在用方法二就赶快更正过来吧!

那么方法二为什么会这么耗时呢?

因为每 +"" 一次,就会调用一次 

public StringBuffer() {
  super(16);
}

方法,这就意味着每 +"" 一次,就会在内存中实例化一个StringBuffer()对象,原因是String类型是final的,其内容是不可变的,所以每次改变其值就要重新new一个对象,如果一个项目中大量使用该方法,不耗时耗内存才怪呢。

个人总结看到这里相信大家都知道了到底哪种方法才是最有效的,int类型转为String类型时使用Integer.toString(i)或String.valueOf(i)方法会比+""高效节能的多。希望阅读此文能提升一下读者的逼格,如果有哪个地方我分析的不对或者有什么更好的建议或更实用的细节还请小伙伴们不吝赐教!

 

转载于:https://www.cnblogs.com/rookieFly-tdiitd/p/4903959.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为服务器故障灯不开机_华为服务器日常维护及故障处理介绍V.ppt

通电策略 power on上电自动开机。 power off上电不自动开机&#xff0c;需按前面板电源按钮才能开机。 Last State上电开机与否取决于上次断电之前的状态&#xff0c;如果是关机状态则通电后不能自动开机&#xff0c;如果是开机状态则通电后可以自动开机。 硬件狗 BMC WDT Acti…

《黑客大曝光:移动应用安全揭秘及防护措施》一2.2 攻击与对策

本节书摘来自华章出版社《黑客大曝光&#xff1a;移动应用安全揭秘及防护措施》一书中的第2章&#xff0c;第2.2节&#xff0c;作者 &#xff08;美&#xff09;Neil Bergman &#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看 2.2 攻击与对策 好&#xff0c…

Android 4.2 通知通过PendingIntent启动Activity失败的问题

今天突然发现在Android 4.2手机上点击通知消息无法打开Activity的问题&#xff0c;具体Logcat信息如下&#xff1a; 01-09 11:37:43.733: WARN/ActivityManager(92): Unable to send startActivity intent java.lang.SecurityException: Permission Denial: starting Intent { …

ubuntu安装sublime

添加sublime text 3的仓库&#xff1a; sudo add-apt-repository ppa:webupd8team/sublime-text-3 更新软件库 sudo apt-get update 安装Sublime Text 3: sudo apt-get install sublime-text-installer 安装sublime2: sudo add-apt-repository ppa:webupd8team/sublime-text-2 …

jdbctemplate mysql 配置_Spring JDBCTemplate配置使用

一、开发环境Windows 10IntelliJ IDEA 2016.1 旗舰版JDK1.8二、项目和数据库结构项目结构&#xff1a;数据库(MySQL 5.5.39)&#xff1a;/*Navicat MySQL Data TransferSource Server : localhostSource Server Version : 50539Source Host : localhost:3306Source Database : …

细数家庭安防五大乱象 何时能步入正轨

虽然智能家居行业在我国的成长已逾十个年头了&#xff0c;但是目前市场离成型仍然有一段距离。市场上可谓“乱象”丛生&#xff0c;这些绊脚石严重阻碍了行业的良性发展。市场乱象繁生&#xff0c;智能家居从概念炒作到价格高抬&#xff0c;相关预测显示&#xff0c;若真如电商…

HDU 1181 变形课

Problem Description呃......变形课上Harry碰到了一点小麻烦,由于他并不像Hermione那样可以记住全部的咒语而任意的将一个棒球变成刺猬什么的,可是他发现了变形咒语的一个统一规律:假设咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体. Harry已经将他所会的…

多线程(同步代码块和同步函数)

线程安全问题 当多条语句在操作同一个线程共享数据时&#xff0c;一个线程对多条语句只执行了一部分&#xff0c;还没有执行完&#xff0c; 另一个线程参与进来执行。导致共享数据的错误。解决办法&#xff1a; 对多条操作共享数据的语句&#xff0c;只能让一个线程都执行…

没有基础学python_python没有基础好学吗

什么是Python&#xff1f;Python是一种计算机程序设计语言。你可能已经听说过很多种流行的编程语言&#xff0c;比如非常难学的C语言&#xff0c;非常流行的Java语言&#xff0c;适合初学者的Basic语言&#xff0c;适合网页编程的JavaScript语言等&#xff0c;Python是他们其中…

C++中的头文件和源文件

一、C编译模式 通常&#xff0c;在一个C程序中&#xff0c;只包含两类文件——cpp文件和h文件。cpp文件被称作C源文件&#xff0c;里面放的都是C的源代码&#xff1b;h文件则被称作C头文件&#xff0c;里面放的也是C的源代码。 C 语言支持“分别编译”&#xff08;separ…

Hibernate 事物隔离级别 深入探究

目录 一、数据库事务的定义 二、数据库事务并发可能带来的问题 三、数据库事务隔离级别 四、使用Hibernate设置数据库隔离级别 五、使用悲观锁解决事务并发问题 六、使用乐观锁解决事务并发问题 Hibernate事务与并发问题处理&#xff08;乐观锁与悲观锁&#xff09; 一、数据库…

Linked List Cycle II - LeetCode

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note: Do not modify the linked list. Follow up:Can you solve it without using extra space? 思路&#xff1a;维护两个指针slow和fast。先判断是否存在环。 在判断是否…

mysql 无论输入什么都是现实 not found_NotAPanda

前言面试竞争力越来越大&#xff0c;是时候撸一波Vue和React源码啦&#xff1b;本文从20个层面来对比Vue和React的源码区别&#xff1b;如果需要了解API的区别&#xff0c;请戳&#xff1a;Vue 开发必须知道的 36 个技巧React 开发必须知道的 34 个技巧文章源码&#xff1a;请戳…

这五张PPT告诉你,如何打造无人驾驶“最强大脑”

“英特尔在谈无人驾驶&#xff0c;会成为汽车制造商吗?NO!我们要为无人驾驶提供从车、连接到云的‘最强大脑’。” 在昨天于北京举行的英特尔无人驾驶分享会上&#xff0c;英特尔无人驾驶事业部中国区市场总监徐伟杰在主旨演讲中开门见山。 这也是英特尔无人驾驶事业部去年11月…

javascript之ua与urlSchema

我们首先拿到浏览器ua: 1 var ua navigator.userAgent; 1 if (ua.indexOf("MicroMessenger") > -1) { 2 alert("微信浏览器"); 3 } 1 if (ua.indexOf("iPhone") > -1) { 2 alert("iphone"); 3 } 其…

ezdpl Linux自动化部署实战

最近把ezdpl在生产环境中实施了&#xff0c;再加上这段时间的一些修改&#xff0c;一并介绍一下。再次申明&#xff1a; ezdpl不是开箱即用的&#xff0c;需要根据自己的应用环境定制。对初学者来说使用起来反倒困难更多、风险更大。它不是一个通用的项目&#xff0c;更多的是提…

无法打开输入文件mysql_错误LNK1181,pip安装“无法打开输入文件”mysqlclient.lib'...

我是Python新手&#xff0c;正在尝试安装mysql模块&#xff0c;但是在解决了其他5个问题之后&#xff0c;我现在遇到了一个问题&#xff0c;当我尝试安装该模块时&#xff0c;会出现以下日志&#xff1a;PS C:\Users\poste> pip install mysqlCollecting mysqlUsing cached …

俄罗斯将封杀LinkedIn 推动个人数据本地化

北京时间11月11日上午消息&#xff0c;莫斯科一家法院本周四支持了在俄罗斯封杀职业社交网站LinkedIn的决定。 俄罗斯联邦通信监管局&#xff08;Roskomnadzor&#xff09;之前要求国内外企业从2015年9月开始&#xff0c;必须将所有俄罗斯用户的个人数据存储在该国境内。Linked…

python的datetime举例_Python datetime模块的使用示例

1、获取当前年月日时分秒# -*- encodingutf-8 -*-import datetimenow datetime.datetime.now()print("now:{}".format(now))year now.yearprint("year:{}".format(year))month now.monthprint("month:{}".format(month))day now.dayprint(&q…

vs2015 去除 git 源代码 绑定,改成向tfs添加源码管理

除了下文的方法是将源码管理从git改成tfs之外&#xff0c;还要做以下几步即可 向tfs添加源码 打开源码管理(管理连接)&#xff0c;双击打开你要向其中添加的tfs连接选中该解决方案&#xff0c;右键 将解决方案添加到源码管理嵌入完毕vs2015 去除 git 源代码 绑定 第一次碰到这个…