開發實戰細節之——關于整型轉換為字符串類型的性能與實現分析

細節決定成敗,開發中往往從一些細節就可以看出一個程序員的開發水準,下面我就給大家分享一下開發中最最常見的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.pswp.cn/news/258175.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258175.shtml
英文地址,請注明出處:http://en.pswp.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 源代碼 綁定 第一次碰到這個…