Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is java.util.Scanner that slow?

Tags:

java

android

In a Android application I want to use Scanner class to read a list of floats from a text file (it's a list of vertex coordinates for OpenGL). Exact code is:

Scanner in = new Scanner(new BufferedInputStream(getAssets().open("vertexes.off")));
final float[] vertexes = new float[nrVertexes];
for(int i=0;i<nrVertexFloats;i++){
    vertexes[i] = in.nextFloat();
}

It seems however that this is incredibly slow (it took 30 minutes to read 10,000 floats!) - as tested on the 2.1 emulator. What's going on? I don't remember Scanner to be that slow when I used it on the PC (truth be told I never read more than 100 values before). Or is it something else, like reading from an asset input stream?

Thanks for the help!

like image 386
Cristian Vrabie Avatar asked Mar 15 '10 11:03

Cristian Vrabie


People also ask

Is Scanner in Java slow?

The scanner has a little buffer(1KB byte buffer). The scanner is slow as it does the parsing of input data.

What is faster than Scanner in Java?

BufferedReader is a bit faster as compared to Scanner because the Scanner does the parsing of input data and BufferedReader simply reads a sequence of characters.

Is Scanner slower than BufferedReader faster?

BufferedReader is a bit faster as compared to scanner because the scanner does parsing of input data and BufferedReader simply reads a sequence of characters.

Why is Scanner slow?

If scanning becomes slower after scanning continuously with the ADF for a long time, the scanner may have automatically slowed down to protect the scanner mechanism from overheating or becoming damaged. Let the scanner rest with the power on for 30 minutes, then try scanning again.


2 Answers

As other posters have stated it's more efficient to include the data in a binary format. However, for a quick fix I've found that replacing:

scanner.nextFloat();

with

Float.parseFloat(scanner.next());

is almost 7 times faster.

The source of the performance issues with nextFloat are that it uses a regular expression to search for the next float, which is unnecessary if you know the structure of the data you're reading beforehand.

It turns out most (if not all) of the next* use regular expressions for a similar reason, so if you know the structure of your data it's preferable to always use next() and parse the result. I.E. also use Double.parseDouble(scanner.next()) and Integer.parseInt(scanner.next()).

Relevant source: https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/util/Scanner.java

like image 148
Ian Newson Avatar answered Oct 22 '22 00:10

Ian Newson


Don't know about Android, but at least in JavaSE, Scanner is slow.

Internally, Scanner does UTF-8 conversion, which is useless in a file with floats.

Since all you want to do is read floats from a file, you should go with the java.io package.

The folks on SPOJ struggle with I/O speed. It's is a Polish programming contest site with very hard problems. Their difference is that they accept a wider array of programming languages than other sites, and in many of their problems, the input is so large that if you don't write efficient I/O, your program will burst the time limit.

Of course, I advise against writing your own float parser, but if you need speed, that's still a solution.

like image 27
Leonel Avatar answered Oct 22 '22 01:10

Leonel