Skip to main content
Fix from JS1
Source Link
rolfl
  • 98.2k
  • 17
  • 220
  • 419
private static final String[] IPMAP = buildIPMap();
private static final String[] buildIPMap() {
    String[] ret = new String[256];
    for (int i = 0; i < ret.length; i++) {
        int[] bits = new int[8];
        for (int b = 0; b < 8; b++) {
            if ((i & (1 << b)) ==!= 10) {
                bits[b] = 1;
            }
        }
        final String bitwords = String.format("%d%d%d%d%d%d%d%d", bits[7], bits[6], bits[5], bits[4], bits[3], bits[2], bits[1], bits[0]);
        ret[i] = bitwords;
    }
    return ret;
}
private static final String[] IPMAP = buildIPMap();
private static final String[] buildIPMap() {
    String[] ret = new String[256];
    for (int i = 0; i < ret.length; i++) {
        int[] bits = new int[8];
        for (int b = 0; b < 8; b++) {
            if ((i & (1 << b)) == 1) {
                bits[b] = 1;
            }
        }
        final String bitwords = String.format("%d%d%d%d%d%d%d%d", bits[7], bits[6], bits[5], bits[4], bits[3], bits[2], bits[1], bits[0]);
        ret[i] = bitwords;
    }
    return ret;
}
private static final String[] IPMAP = buildIPMap();
private static final String[] buildIPMap() {
    String[] ret = new String[256];
    for (int i = 0; i < ret.length; i++) {
        int[] bits = new int[8];
        for (int b = 0; b < 8; b++) {
            if ((i & (1 << b)) != 0) {
                bits[b] = 1;
            }
        }
        final String bitwords = String.format("%d%d%d%d%d%d%d%d", bits[7], bits[6], bits[5], bits[4], bits[3], bits[2], bits[1], bits[0]);
        ret[i] = bitwords;
    }
    return ret;
}
Typo fixes.
Source Link
Brythan
  • 7k
  • 3
  • 22
  • 37

Your slow code is slow because of the multiple String instances you create, and repleacereplace, and so on. It is 6 times slower becauseyoubecause you have a binString, which you then format in to a padded string (which likely has internal string representations, and then finally you search/replace values in that too.

There is a different way to solve these sorts of problems, though, and that is to pre-process a chunk of the work. I was dissappointeddisappointed that this approach was only slightly faster than your fast version, though.

Your slow code is slow because of the multiple String instances you create, and repleace, and so on. It is 6 times slower becauseyou have a binString, which you then format in to a padded string (which likely has internal string representations, and then finally you search/replace values in that too.

There is a different way to solve these sorts of problems, though, and that is to pre-process a chunk of the work. I was dissappointed that this approach was only slightly faster than your fast version, though.

Your slow code is slow because of the multiple String instances you create, and replace, and so on. It is 6 times slower because you have a binString, which you then format in to a padded string (which likely has internal string representations, and then finally you search/replace values in that too.

There is a different way to solve these sorts of problems, though, and that is to pre-process a chunk of the work. I was disappointed that this approach was only slightly faster than your fast version, though.

Source Link
rolfl
  • 98.2k
  • 17
  • 220
  • 419

Your slow code is slow because of the multiple String instances you create, and repleace, and so on. It is 6 times slower becauseyou have a binString, which you then format in to a padded string (which likely has internal string representations, and then finally you search/replace values in that too.

The fast code does not have any transformations, it is simply an additive process, and Strings get created just once, and there is only one creation... of a String, and 1 creation of a char[] array

There are two ways you can improve the performance of your fast method:

  1. set the initial size of the StringBuilder(...) which will always be 32.
  2. create a single PAD array, and use a sub-portion of it for the results

I have the code:

private static final char[] PAD_ARRAY = new char[8];

static {
    Arrays.fill(PAD_ARRAY, '0');
}

public static String fast(String ip) {

    StringBuilder bStringBuilder = new StringBuilder(32);
    String ipParts[] = ip.split("\\.");

    for (String ipPart : ipParts) {

        String binString = Integer.toBinaryString(Integer.parseInt(ipPart));
        bStringBuilder.append(PAD_ARRAY, 0, 8 - binString.length()).append(binString);
    }
    //System.out.println(bStringBuilder.toString());
    return bStringBuilder.toString();
}

There is a different way to solve these sorts of problems, though, and that is to pre-process a chunk of the work. I was dissappointed that this approach was only slightly faster than your fast version, though.

Consider this code which pre-populates an array of binary representations:

private static final String[] IPMAP = buildIPMap();
private static final String[] buildIPMap() {
    String[] ret = new String[256];
    for (int i = 0; i < ret.length; i++) {
        int[] bits = new int[8];
        for (int b = 0; b < 8; b++) {
            if ((i & (1 << b)) == 1) {
                bits[b] = 1;
            }
        }
        final String bitwords = String.format("%d%d%d%d%d%d%d%d", bits[7], bits[6], bits[5], bits[4], bits[3], bits[2], bits[1], bits[0]);
        ret[i] = bitwords;
    }
    return ret;
}

Now, you can have the following code:

public static String mapped(String ip) {
    StringBuilder sb = new StringBuilder(32);
    for (String block : ip.split("\\.")) {
        sb.append(IPMAP[Integer.parseInt(block)]);
    }
    return sb.toString();
}

In my testing, the different solutions have the following characteristics:

Task Routing -> Slow: (Unit: MICROSECONDS)
  Count    :    100000      Average  :    3.8060
  Fastest  :    2.2880      Slowest  : 9464.0360
  95Pctile :    6.3870      99Pctile :   11.6600
  TimeBlock : 8.366 4.366 5.914 3.657 2.696 2.944 2.547 2.724 2.443 2.407
  Histogram : 84962 12731  1761   277   173    81     9     0     1     4     0     0     1

Task Routing -> Fast: (Unit: MICROSECONDS)
  Count    :   100000      Average  :   0.4710
  Fastest  :   0.2910      Slowest  : 129.1240
  95Pctile :   0.7420      99Pctile :   1.9220
  TimeBlock : 1.442 0.397 0.485 0.353 0.331 0.360 0.339 0.338 0.335 0.334
  Histogram : 84577 12020  2676   294   305    95    20     4     9

Task Routing -> Mapped: (Unit: MICROSECONDS)
  Count    :    100000      Average  :    0.4540
  Fastest  :    0.2890      Slowest  : 1663.1440
  95Pctile :    0.6670      99Pctile :    1.6780
  TimeBlock : 1.392 0.381 0.441 0.341 0.334 0.342 0.327 0.331 0.327 0.331
  Histogram : 87774  9244  2313   283   297    69    13     0     6     0     0     0     1