3

Rather than parsing a byte array to an ASCII string then converting the string to say an integer, it should be more efficient to parse the byte array directly to an integer.

byte[] token = "24000".getBytes(Charset.forName("US-ASCII"));

The following code can do this:

int n = 0;
for (byte b : token)
  n = 10*n + (b-'0');

Versus the common approach:

int n = Integer.parseInt(new String(token));

Ref: Dave's answer here >> Converting US-ASCII encoded byte to integer and back

Is there a comprehensive solution that skips String creation and goes straight to result?

Please stop marking the question for closing due to this question: Convert a byte array to integer in java and vice versa

It deals with non-encoded bytes.

It does not answer my question.

Community
  • 1
  • 1
BAR
  • 15,909
  • 27
  • 97
  • 185
  • Sorry, the duplicate question does not answer for the same byte format as this question. Voted to reopen. Note that most of the time you should not worry about performance items like this, just build in the naive way and measure performance. (then possibly fix if you have a problem). – Thirler Feb 02 '15 at 08:08
  • @Thirler No problem; was just about to say it did not look the same. I am following the naive version currently as the boost is not too big of a deal, but I would be somewhat surprised if this has not been implemented yet given the increased efficiency. – BAR Feb 02 '15 at 08:10
  • Well, the question isn't a duplicate, but now that I think of it, it's still off-topic due to being a request for a recommendation of an off-site resource. – RealSkeptic Feb 02 '15 at 08:27
  • @RealSkeptic edited to follow rules... although I could ask if a particular library, say Guava, had these features.. right? – BAR Feb 02 '15 at 08:28
  • What is wrong with the code you already have in the question? – Alex - GlassEditor.com Feb 02 '15 at 08:38
  • @Alex It is not all inclusive. How about double, long, etc. Or parsing errors. There should be a way to do this without reinventing the wheel. – BAR Feb 02 '15 at 08:39
  • 1
    In the Java standard library, there isn't one. – yole Feb 02 '15 at 08:41
  • I don't think this is a good idea. Have you benchmarked the code? If you really want efficiency, send the number in binary. – xehpuk Feb 02 '15 at 09:10
  • I suggest you *test* and *measure,* and do so *before* you decide this is a major bottleneck that needs custom code. You will probably be surprised to learn that it isn't. – user207421 Feb 02 '15 at 09:27
  • @EJP Its not a bottleneck in my code, but it sure would be nice to get a 'free' performance boost, however negligible it may seem. I think its somewhat obvious skipping string creation will provide a faster result. – BAR Feb 02 '15 at 14:56

1 Answers1

1

The Java library doesn't seem to have a dedicated tool for the job, but it sure has enough tools to write one yourself.

In my opinion, if you're worried about performance since turning byte arrays to ints is a bottleneck in your code, then I suggest writing your own solution based on the piece of code you provided. If it isn't, then just use parseInt for easier readability.

In any case, if Java had a tool for doing this, it would use pretty much the same code under the hood. That's pretty much what Integer.parseInt() does (except it covers other bases, negative numbers, and is safer):

 public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        int result = 0;
        boolean negative = false;
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;
        int multmin;
        int digit;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Integer.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }
Malt
  • 28,965
  • 9
  • 65
  • 105
  • I have looked at this before and wondered why they don't just generalize that code to work for String and ByteArray/CharArray. Maybe that is a better question to ask... One-upped your post. – BAR Feb 02 '15 at 14:58