Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

226
LINES

< > BotCompany Repo | #1033787 // BufferedImage / VolatileImage Benchmark

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Libraryless. Click here for Pure Java version (6950L/41K).

1  
// from https://github.com/ideastorm/Benchmark
2  
3  
/* My results on ThinkPad, JDK 17:
4  
5  
3 Buffers
6  
   Direct Buffer Average 324.43
7  
  Buffered Image Average 137.89
8  
  Reuse Buffered Average 183.25
9  
      ARGB Image Average 133.57
10  
Reuse ARGB Image Average 173.53
11  
  Volatile Image Average 43159.51
12  
  Reuse Volatile Average 521.36
13  
2 Buffers
14  
   Direct Buffer Average 326.72
15  
  Buffered Image Average 124.76
16  
  Reuse Buffered Average 170.78
17  
      ARGB Image Average 123.15
18  
Reuse ARGB Image Average 157.24
19  
  Volatile Image Average 34659.11
20  
  Reuse Volatile Average 731.17
21  
1 Buffers
22  
   Direct Buffer Average 396.43
23  
  Buffered Image Average 155.31
24  
  Reuse Buffered Average 208.33
25  
      ARGB Image Average 162.80
26  
Reuse ARGB Image Average 191.03
27  
  Volatile Image Average 39582.93
28  
  Reuse Volatile Average 752.04
29  
30  
*/
31  
32  
p { Benchmark.main(args); }
33  
34  
sclass Benchmark implements Callable<Long> {
35  
36  
    private static final int INNER_LOOP_COUNT = 250;
37  
    private static final int OUTER_LOOP_COUNT = 5;
38  
    private static final int NORMALIZE_LOOP_COUNT = 3;
39  
40  
    // Window Objects
41  
    static javax.swing.JFrame frame;
42  
    static javax.swing.JPanel panel;
43  
44  
    private final Consumer<Consumer<Graphics2D>> painter;
45  
46  
    private Benchmark(Consumer<Consumer<Graphics2D>> painter) {
47  
        this.painter = painter;
48  
    }
49  
50  
    @Override
51  
    public Long call() {
52  
        Font font = panel.getFont().deriveFont(30f);
53  
        long start = System.nanoTime();
54  
        for (int i = 0; i < INNER_LOOP_COUNT; i++) {
55  
            final String frameCount = "" + i;
56  
            painter.accept((Graphics2D g) -> {
57  
                g.setColor(Color.BLACK);
58  
                g.setFont(font);
59  
                g.drawString(frameCount, 30, 100);
60  
            });
61  
        }
62  
        long end = System.nanoTime();
63  
        return end - start;
64  
    }
65  
66  
    public static void main(String[] args) {
67  
68  
        // Create JFrame
69  
        frame = new javax.swing.JFrame("Benchmark");
70  
        frame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
71  
        // Create JPanel
72  
        panel = new javax.swing.JPanel(false);
73  
        panel.setPreferredSize(new java.awt.Dimension(1280, 720));
74  
        frame.setContentPane(panel);
75  
76  
        ClassLoader classloader = ClassLoader.getSystemClassLoader();
77  
78  
        // Load Test Image
79  
        try {
80  
            testimage = loadImage2(#1103053);
81  
            blackimage = loadImage2(#1103052);
82  
83  
            // Set Window Visible and get Panel Graphics
84  
            frame.pack();
85  
            frame.setVisible(true);
86  
            panelGraphics = panel.getGraphics();
87  
88  
            for (int normalizeIndex = 0; normalizeIndex < NORMALIZE_LOOP_COUNT; normalizeIndex++) {
89  
            
90  
                printVars(+normalizeIndex);
91  
92  
                // Start Tests and Display Results
93  
                for (int bufferCount = 3; bufferCount > 0; bufferCount--) {
94  
                    printVars(+bufferCount);
95  
                    frame.createBufferStrategy(bufferCount);
96  
                    List<Long> directBufferTimes = new ArrayList<>();
97  
                    List<Long> bufferedImageTimes = new ArrayList<>();
98  
                    List<Long> volatileImageTimes = new ArrayList<>();
99  
                    List<Long> bufferedArgbTimes = new ArrayList<>();
100  
                    List<Long> reuseBufferedTimes = new ArrayList<>();
101  
                    List<Long> reuseVolatileTimes = new ArrayList<>();
102  
                    List<Long> reuseArgbBufrTimes = new ArrayList<>();
103  
                    for (int i = 0; i < OUTER_LOOP_COUNT; i++) {
104  
                        printVars(+normalizeIndex, +bufferCount, +i);
105  
                        frame.setTitle("Benchmark - Direct Buffer");
106  
                        directBufferTimes.add(new Benchmark(Benchmark::drawDoubleBuffer).call());
107  
                        frame.setTitle("Benchmark - Buffered Image");
108  
                        bufferedImageTimes.add(new Benchmark(Benchmark::drawBufferedImage).call());
109  
                        frame.setTitle("Benchmark - Reuse Buffered Image");
110  
                        reuseBufferedTimes.add(new Benchmark(Benchmark::reuseBufferedImage).call());
111  
                        frame.setTitle("Benchmark - ARGB Buffered Image");
112  
                        bufferedArgbTimes.add(new Benchmark(Benchmark::drawArgbBufferedImage).call());
113  
                        frame.setTitle("Benchmark - Reuse ARGB Buffered Image");
114  
                        reuseArgbBufrTimes.add(new Benchmark(Benchmark::reuseArgbBufferedImage).call());
115  
                        frame.setTitle("Benchmark - Volatile Image");
116  
                        volatileImageTimes.add(new Benchmark(Benchmark::drawVolatileImage).call());
117  
                        frame.setTitle("Benchmark - Reuse Volatile Image");
118  
                        reuseVolatileTimes.add(new Benchmark(Benchmark::reuseVolatileImage).call());
119  
                    }
120  
                    /*
121  
                     * Java benchmarks usually have to "warm up".  By running it multiple times and ignoring the first runs, we 
122  
                     * allow the JVM to normalize its heap allocation, so garbage collection doesn't affect the results as much.
123  
                     */
124  
                    if (normalizeIndex == NORMALIZE_LOOP_COUNT - 1) {
125  
//                        bufferedImageTimes.forEach(t -> System.out.printf("Buffered Image %01.2f\n", calcFps(t)));
126  
//                        volatileImageTimes.forEach(t -> System.out.printf("Volatile Image %01.2f\n", calcFps(t)));
127  
//                        directBufferTimes.forEach(t -> System.out.printf("Direct Buffer  %01.2f\n", calcFps(t)));
128  
                        System.out.printf("%d Buffers\n", bufferCount);
129  
                        System.out.printf("   Direct Buffer Average %01.2f\n", directBufferTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
130  
                        System.out.printf("  Buffered Image Average %01.2f\n", bufferedImageTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
131  
                        System.out.printf("  Reuse Buffered Average %01.2f\n", reuseBufferedTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
132  
                        System.out.printf("      ARGB Image Average %01.2f\n", bufferedArgbTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
133  
                        System.out.printf("Reuse ARGB Image Average %01.2f\n", reuseArgbBufrTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
134  
                        System.out.printf("  Volatile Image Average %01.2f\n", volatileImageTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
135  
                        System.out.printf("  Reuse Volatile Average %01.2f\n", reuseVolatileTimes.stream().mapToDouble(Benchmark::calcFps).average().getAsDouble());
136  
                    }
137  
                }
138  
            }
139  
140  
            frame.setVisible(false);
141  
        } catch (Throwable e) {
142  
            e.printStackTrace();
143  
        }
144  
        System.exit(0); //force shutdown
145  
    }
146  
147  
    static double calcFps(Long nanoTime) {
148  
        return INNER_LOOP_COUNT * 1_000_000_000.0 / nanoTime;
149  
    }
150  
151  
    // Test Image
152  
    static java.awt.Image testimage;
153  
    static java.awt.Image blackimage;
154  
    private static BufferedImage staticBuffered;
155  
    private static BufferedImage staticArgbBuffered;
156  
    private static VolatileImage staticVolatile;
157  
158  
    // Draw Graphics
159  
    static Graphics panelGraphics;
160  
161  
    static void drawUsingImageBuffer(Consumer<Graphics2D> frameMarker, Image buffer) {
162  
        Graphics2D imageGraphics = (Graphics2D) buffer.getGraphics();
163  
        imageGraphics.drawImage(testimage, 0, 0, 1280, 720, null);
164  
        frameMarker.accept(imageGraphics);
165  
        panelGraphics.drawImage(buffer, 0, 0, 1280, 720, null);
166  
    }
167  
168  
    static void drawBufferedImage(Consumer<Graphics2D> frameMarker) {
169  
        BufferedImage buffer = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_RGB);
170  
        drawUsingImageBuffer(frameMarker, buffer);
171  
    }
172  
173  
    static void reuseBufferedImage(Consumer<Graphics2D> frameMarker) {
174  
        if (staticBuffered == null) {
175  
            staticBuffered = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_RGB);
176  
        }
177  
        drawUsingImageBuffer(frameMarker, staticBuffered);
178  
    }
179  
180  
    static void drawArgbBufferedImage(Consumer<Graphics2D> frameMarker) {
181  
        BufferedImage buffer = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_ARGB);
182  
        drawUsingImageBuffer(frameMarker, buffer);
183  
    }
184  
185  
    static void reuseArgbBufferedImage(Consumer<Graphics2D> frameMarker) {
186  
        if (staticArgbBuffered == null) {
187  
            staticArgbBuffered = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_ARGB);
188  
        }
189  
        drawUsingImageBuffer(frameMarker, staticArgbBuffered);
190  
    }
191  
192  
    static void drawVolatileImage(Consumer<Graphics2D> frameMarker) {
193  
        VolatileImage volatileImage = panel.createVolatileImage(1280, 720);
194  
        drawUsingImageBuffer(frameMarker, volatileImage);
195  
    }
196  
197  
    static void reuseVolatileImage(Consumer<Graphics2D> frameMarker) {
198  
        if (staticVolatile == null || staticVolatile.contentsLost()) {
199  
            staticVolatile = panel.createVolatileImage(1280, 720);
200  
        }
201  
        drawUsingImageBuffer(frameMarker, staticVolatile);
202  
    }
203  
204  
    static void drawDoubleBuffer(Consumer<Graphics2D> frameMarker) {
205  
        Insets insets = frame.getInsets();
206  
        Toolkit.getDefaultToolkit().sync();
207  
        BufferStrategy strategy = frame.getBufferStrategy();
208  
        if (strategy != null) {
209  
            do {
210  
                do {
211  
                    Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics();
212  
                    graphics.translate(insets.left, insets.top);
213  
                    graphics.drawImage(testimage, 0, 0, 1280, 720, null);
214  
                    frameMarker.accept(graphics);
215  
                    graphics.dispose();
216  
                } while (strategy.contentsRestored());
217  
                strategy.show();
218  
            } while (strategy.contentsLost());
219  
        } else {
220  
            Graphics2D graphics = (Graphics2D) panelGraphics;
221  
            graphics.drawImage(testimage, insets.left, insets.top, 1280, 720, null);
222  
            frameMarker.accept(graphics);
223  
        }
224  
225  
    }
226  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033787
Snippet name: BufferedImage / VolatileImage Benchmark
Eternal ID of this version: #1033787/4
Text MD5: 4d543aa3009d91c46d39ee58464decdb
Transpilation MD5: f5605a7f9124f7e3f1e00127b58d6a2e
Author: stefan
Category: javax / gui
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-04 21:39:13
Source code size: 10412 bytes / 226 lines
Pitched / IR pitched: No / No
Views / Downloads: 315 / 989
Version history: 3 change(s)
Referenced in: [show references]