gocha

Parse decimal string in byte[] (lightweight parseInt)

Oct 23rd, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.54 KB | None | 0 0
  1. // byte配列(10進数文字列)から数値を取得
  2. public class Test
  3. {
  4.     /**
  5.      * byte配列(10進数文字列)から数値を取得
  6.      * <p>
  7.      * 特別にパフォーマンスを要求する場合を除いて、
  8.      * Integer.parseInt(new String(...)) を使うことを推奨します。
  9.      * </p>
  10.      * @param bArray 文字列が格納された配列
  11.      * @param startIndex 読み取り開始インデックス
  12.      * @return 取得した数値
  13.      */
  14.     public static int parseIntFromBytes(byte[] bArray, int startIndex)
  15.     {
  16.         long number = 0;
  17.         boolean signed = false;
  18.  
  19.         // 符号を取得
  20.         if (bArray.length > 0)
  21.         {
  22.             if (bArray[startIndex] == '-')
  23.             {
  24.                 signed = true;
  25.                 startIndex++;
  26.             }
  27.             else if (bArray[startIndex] == '+')
  28.             {
  29.                 startIndex++;
  30.             }
  31.         }
  32.  
  33.         // 整数値を取得
  34.         for (int i = startIndex; i < bArray.length; i++)
  35.         {
  36.             byte c = bArray[i];
  37.             if (c >= '0' && c <= '9')
  38.             {
  39.                 number *= 10;
  40.                 number += (c - '0');
  41.  
  42.                 if (number > ((long)Integer.MAX_VALUE + (signed ? 1 : 0)))
  43.                 {
  44.                     throw new ArithmeticException("Arithmetic overflow. Number too large.");
  45.                 }
  46.             }
  47.             else if (c == 0 || c == '\r' || c == '\n')
  48.             {
  49.                 break;
  50.             }
  51.             else
  52.             {
  53.                 throw new NumberFormatException("For character 0x" + String.format("%02x", c & 0xff) + ".");
  54.             }
  55.         }
  56.  
  57.         // 負数であれば符号を反転
  58.         if (signed)
  59.         {
  60.             number = -number;
  61.         }
  62.  
  63.         return (int)number;
  64.     }
  65.  
  66.     // テスト
  67.     public static void main(String[] args)
  68.     {
  69.         try
  70.         {
  71.             if (args.length == 0)
  72.             {
  73.                 System.out.println("Give me a number.");
  74.                 return;
  75.             }
  76.  
  77.             final int repeatCount = 5 * 1024 * 1024;
  78.             byte[] bytes = args[0].getBytes();
  79.             long tickStart, tickEnd;
  80.             long dummy = 0;
  81.  
  82.             // parseIntFromBytes
  83.             System.out.println("parseIntFromBytes start");
  84.             tickStart = System.currentTimeMillis();
  85.             for (int i = 0; i < repeatCount; i++)
  86.             {
  87.                 dummy += parseIntFromBytes(bytes, 0);
  88.             }
  89.             tickEnd = System.currentTimeMillis();
  90.             System.out.println("parseIntFromBytes end [" + (tickEnd - tickStart) + " ms]");
  91.  
  92.             // parseInt
  93.             System.out.println("parseInt start");
  94.             tickStart = System.currentTimeMillis();
  95.             for (int i = 0; i < repeatCount; i++)
  96.             {
  97.                 dummy += Integer.parseInt(new String(bytes));
  98.             }
  99.             tickEnd = System.currentTimeMillis();
  100.             System.out.println("parseInt end [" + (tickEnd - tickStart) + " ms]");
  101.  
  102.             // 未使用変数扱いされたくないので出力
  103.             System.out.println(dummy);
  104.         }
  105.         catch (Exception e)
  106.         {
  107.             e.printStackTrace();
  108.         }
  109.     }
  110. }
Add Comment
Please, Sign In to add comment