简体   繁体   中英

Why GZIPInputStream takes quite long time?

System.out.println("Input String length : " + str.length());
System.out.println("SWB==="+sw.getTime());
byte[] bytes = Base64.decodeBase64(str);
System.out.println("SWB==="+sw.getTime());
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
BufferedReader bf = new BufferedReader(new InputStreamReader(gis));
String outStr = "";
String line;
while ((line=bf.readLine())!=null) {
     outStr += line;
}
System.out.println("SWB==="+sw.getTime());
System.out.println("Output String lenght : " + outStr.length());

The above code prints

SWB===1
SWB===4
SWB===27052
Output String lenght : 1750825

But the compression of the same string takes quite short time (less than 100ms). What am i doing wrong here ? (other than my bad way of debug comments)

The problem is this:

String line;
while ((line=bf.readLine())!=null) {
     outStr += line;
}

Each String concatenation will implicitly create a StringBuilder to append the 2 strings, then call toString() method on it.

Use a single StringBuilder to drastically speed this up:

StringBuilder sb = new StringBuilder(65536); // Consider a large initial size
String line
while ((line=bf.readLine())!=null) {
     sb.append(line);
}

// OutString is in the sb StringBuilder
String outStr = sb.toString();

Also consider a large initial StringBuilder size to even minimize the internal reallocations. In the example I used 64KB, but if you know your result String will be much bigger, you can even safely use multiple MBs.

Also consider not calling toString() on the result if you don't need it. StringBuilder implements CharSequence and many methods accept CharSequence as well as String s.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM