1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package Torello.Java;

import java.util.Random;


// This Class only implements one method, but does it in three separate ways.  These are only 
// retained so that you may view these for whatever reason you want.  Chat-GPT actually wrote 
// all three of the following methods.  Then, when I asked how much of a difference it would 
// actually make or actually mean - it went ahead and wrote me a Bench Mark Testing Routine.
// 
// The numbers were exactly as it explained, with the String.format solution being extremely 
// slow, and the variant using java.lang.StringBuilder being only marginally slower than the 
// optimized variant which uses the 'char[] buffer'
//
// As it says below, all this method does is convert a Java Integer into a Java-Strinng, but 
// does so in a way that allows the output to be inserted into Java-Code in a more readable 
// way.  Specifically, the following Syntax is somewhat less commonly used in Java, but still 
// very useful.
//
// int myInt = 123_456_789
//
// The above int has a value of One-Hundred Twenty-Three Million, four-hundred Fifty-Six
// Thousand, Seven-Hundred Eight-Nine
// 
// IMPORTANT NOTE: This method would emit the String "123_456_7890"
// 
// YES - THIS IS AN EXTREMELY TRIVIAL THING, BUT INTERESTING TO TEST & DOCUMENT, NONE THE LESS!

class IntegralToJavaLiteral
{
    // ********************************************************************************************
    // ********************************************************************************************
    // Converts a Java Integer: 123456  ==>  Into a String using the Under-Score: "123_456"
    // ********************************************************************************************
    // ********************************************************************************************

    static String charBuffer(int n)
    {
        final char[]    buf = new char[24];
        final boolean   neg = n < 0;

        int pos     = buf.length;   
        int group   = 0;

        long x = neg ? (-1 * n) : n;

        do
        {
            final int d = (int)(x % 10);

            buf[--pos] = (char)('0' + d);

            x /= 10;
            group++;

            if ((x != 0) && (group == 3))
            {
                buf[--pos]  = '_';
                group       = 0;
            }
        }
        while (x != 0);

        if (neg) buf[--pos] = '-';

        return new String(buf, pos, buf.length - pos);
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // Two slightly less efficients variants of the exact same thing
    // ********************************************************************************************
    // ********************************************************************************************


    private static String builderInsert(int i)
    {
        final String        s   = Integer.toString(i);
        final StringBuilder sb  = new StringBuilder(s);

        for (int pos = sb.length() - 3; pos > 0; pos -= 3) sb.insert(pos, '_');
        return sb.toString();
    }

    private static String fmtReplace(int n)
    { return String.format("%,d", n).replace(',', '_'); }


    // ********************************************************************************************
    // ********************************************************************************************
    // This is actually a "Benchmark Generator" that Chat-GPT wrote for me!
    // ********************************************************************************************
    // ********************************************************************************************


    private static long run(String name, java.util.function.IntFunction<String> f, int[] data, int iters)
    {
        // Warmup
        String sink = null;
        for (int i = 0; i < iters; i++) sink = f.apply(data[i & (data.length-1)]);

        // Measure
        long t0 = System.nanoTime();
        for (int i = 0; i < iters; i++) sink = f.apply(data[i & (data.length-1)]);
        long t1 = System.nanoTime();

        // guard against dead-code elim
        if (sink == null) System.out.println("ignore");
        return t1 - t0;
    }

    public static void main(String[] args)
    {
        final int       N       = 1 << 16;
        final int[]     data    = new int[N];
        final Random    r       = new Random(123);

        for (int i=0;i<N;i++) data[i] = r.nextInt(Integer.MAX_VALUE);

        final int iters = 10_000_000; // adjust to your machine

        long t1 = run("fmtReplace",     IntegralToJavaLiteral::fmtReplace,      data, iters);
        long t2 = run("builderInsert",  IntegralToJavaLiteral::builderInsert,   data, iters);
        long t3 = run("charBuffer",     IntegralToJavaLiteral::charBuffer,      data, iters);

        System.out.printf("fmtReplace   : %.3f s%n", t1/1e9);
        System.out.printf("builderInsert: %.3f s%n", t2/1e9);
        System.out.printf("charBuffer   : %.3f s%n", t3/1e9);
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // I added this afterwards... Perhaps this is over-kill, but uses a 'long' instead of an 'int'
    // ********************************************************************************************
    // ********************************************************************************************


    static String charBufferLong(long v)
    {
        // Special case: negating Long.MIN_VALUE would overflow
        if (v == Long.MIN_VALUE) return "-9_223_372_036_854_775_808";

        final char[]    buf = new char[32];  // safe upper bound
        final boolean   neg = v < 0;

        if (neg) v = -v;

        int pos     = buf.length;
        int group   = 0;

        do
        {
            int d = (int)(v % 10);

            buf[--pos]  = (char)('0' + d);
            v /= 10;
            group++;

            if ((v != 0) && (group == 3))
            {
                buf[--pos]  = '_';
                group       = 0;
            }
        }
        while (v != 0);

        if (neg) buf[--pos] = '-';
        return new String(buf, pos, buf.length - pos);
    }
}