【Java】split()和java.util.StringTokenizer分割字符串的性能比较
原始版本
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter;public class StringGenerator {public static void main(String[] args) {try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("text.text"))) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(1000));str.append("aovnodnvds");writer.write(str.toString());} catch (IOException e) {e.printStackTrace();}} }文件寫進(jìn)去了:
看看能不能讀出來:
讀的出來,那就正式測試吧:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.StringTokenizer;public class SplitTest {public static void main(String[] args) {String str = "";try (BufferedReader reader = new BufferedReader(new FileReader("text.text"))) {str = reader.readLine();} catch (IOException e) {e.printStackTrace();}long time0 = System.currentTimeMillis();StringTokenizer st = new StringTokenizer(str, "#");while (st.hasMoreTokens()) {st.nextToken();}long time1 = System.currentTimeMillis();String[] array = str.split("#");for (String s : array) {}long time2 = System.currentTimeMillis();System.out.println("StringTokenizer的運行時間是:" + (time1-time0));System.out.println("split()的運行時間是:" + (time2-time1));} }運行結(jié)果:
StringTokenizer的運行時間是:9 split()的運行時間是:0文本內(nèi)容×10
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter;public class StringGenerator {public static void main(String[] args) {try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("text.text"))) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(10000));str.append("aovnodnvds");writer.write(str.toString());} catch (IOException e) {e.printStackTrace();}} }運行結(jié)果:
StringTokenizer的運行時間是:10 split()的運行時間是:0文本內(nèi)容×100
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter;public class StringGenerator {public static void main(String[] args) {try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("text.text"))) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(100000));str.append("aovnodnvds");writer.write(str.toString());} catch (IOException e) {e.printStackTrace();}} }看看這3.6MB的文件吧……
運行結(jié)果:
文本內(nèi)容×1000
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter;public class StringGenerator {public static void main(String[] args) {try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("text.text"))) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(1000000));str.append("aovnodnvds");writer.write(str.toString());} catch (IOException e) {e.printStackTrace();}} }慘絕人寰的36M:
運行結(jié)果:
文本內(nèi)容×10000
這個時候虛擬機就有點頂不住,我忘了是1W倍還是10W倍數(shù)據(jù),反正基本在GB級別的時候,虛擬機就崩了……
試著調(diào)了虛擬機,也沒啥用,就試著不在一次寫入,而是改成分批次寫入,每次都是追加模式……
import java.io.FileWriter; import java.io.IOException;public class StringGenerator {public static void main(String[] args) {try (FileWriter writer = new FileWriter("text.text", true)) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(1000000));for (int i = 0; i < 10; i++) {writer.write(str.append("\n").toString());}str.append("aovnodnvds");} catch (IOException e) {e.printStackTrace();}} }360MB數(shù)據(jù)了,可怕……
測試結(jié)果:
StringTokenizer的運行時間是:316 split()的運行時間是:609文本內(nèi)容×10W
import java.io.FileWriter; import java.io.IOException;public class StringGenerator {public static void main(String[] args) {try (FileWriter writer = new FileWriter("text.text", true)) {StringBuilder str = new StringBuilder();str.append("afiaongaoncanivnrfbnavoiadnvonvoron#".repeat(1000000));for (int i = 0; i < 100; i++) {writer.write(str.append("\n").toString());}str.append("aovnodnvds");} catch (IOException e) {e.printStackTrace();}} }一個文件有這么地獄級別的數(shù)據(jù)量——3.96GB,太可怕了 (雖然比起大數(shù)據(jù)的數(shù)據(jù)量,這根本不算個事)
不敢一次讀出來,分了100次換行讀出來:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.StringTokenizer;public class SplitTest {public static void main(String[] args) {String[] strings = new String[100];try (BufferedReader reader = new BufferedReader(new FileReader("text.text"))) {for (int i = 0; i < 100; i++) {strings[i] = reader.readLine();}} catch (IOException e) {e.printStackTrace();}long time0 = System.currentTimeMillis();for (String s : strings) {StringTokenizer st = new StringTokenizer(s, "#");while (st.hasMoreTokens()) {st.nextToken();}}long time1 = System.currentTimeMillis();for (String s : strings) {String[] array = s.split("#");for (String str : array) {}}long time2 = System.currentTimeMillis();System.out.println("StringTokenizer的運行時間是:" + (time1-time0));System.out.println("split()的運行時間是:" + (time2-time1));} }測試結(jié)果:
StringTokenizer的運行時間是:650 split()的運行時間是:1805對比總結(jié)
java.util.StringTokenizer是Java1.0就推出的古老API,在小數(shù)據(jù)量級顯得不如split()簡潔和快速。
但當(dāng)數(shù)據(jù)量變大的時候,由于split()生成的數(shù)據(jù)存儲在數(shù)組中,這個數(shù)組就會很大,很難操作,好在String是引用類型,否則光是開辟這么一大塊空間就已經(jīng)要命了……
所以,數(shù)據(jù)量很大還要讀文件(顯然那會兒都該是數(shù)據(jù)庫了)的時候,可以使用java.util.StringTokenizer,避免使用split()再次開辟一個大數(shù)組!
總結(jié)
以上是生活随笔為你收集整理的【Java】split()和java.util.StringTokenizer分割字符串的性能比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MySQL】向已有主键的表附加主键属性
- 下一篇: 【数字逻辑设计】Logisim构建锁存器