Project

General

Profile

Main.java

Teodor Gorghe, 04/29/2026 06:52 AM

Download (4.34 KB)

 
1
import java.lang.reflect.*;
2
import java.util.*;
3

    
4
public class Main
5
{
6
   private final static List<Class<?>> CLASSES = List.of(
7
      ClassOne.class, ClassTwo.class, ClassThree.class, ClassFour.class, 
8
      ClassFive.class, ClassSix.class, ClassSeven.class, ClassEight.class, 
9
      ClassNine.class, ClassTen.class, ClassEleven.class, ClassTwelve.class
10
   );
11

    
12
   public static void main(String[] args)
13
   {
14
      int iterations = 1000000;
15
      long startTime = System.nanoTime();
16
      for (int i = 0; i < iterations; i++)
17
      {
18
         for (Class<?> cls : CLASSES)
19
         {
20
            try
21
            {
22
               cls.getDeclaredConstructor().newInstance();
23
            }
24
            catch (Exception e)
25
            {
26
               e.printStackTrace();
27
            }
28
         }
29
      }
30
      long endTime = System.nanoTime();
31
      long totalTime = (endTime - startTime);
32
      System.out.println("Total time for non-cached cls.getDeclaredConstructor().newInstance() (ms): " +  totalTime/1000000);
33

    
34
      startTime = System.nanoTime();
35
      for (int i = 0; i < iterations; i++)
36
      {
37
         for (Class<?> cls : CLASSES)
38
         {
39
            try
40
            {
41
               Class<?> ignored = cls.getComponentType();
42
            }
43
            catch (Exception e)
44
            {
45
               e.printStackTrace();
46
            }
47
         }
48
      }
49
      endTime = System.nanoTime();
50
      totalTime = (endTime - startTime);
51
      System.out.println("Total time for non-cached cls.getComponentType() (ms): " +  totalTime/1000000);
52

    
53
      startTime = System.nanoTime();
54
      for (int i = 0; i < iterations; i++)
55
      {
56
         for (Class<?> cls : CLASSES)
57
         {
58
            try
59
            {
60
               Helper.createInstance(cls);
61
            }
62
            catch (Exception e)
63
            {
64
               e.printStackTrace();
65
            }
66
         }
67
      }
68
      endTime = System.nanoTime();
69
      totalTime = (endTime - startTime);
70
      System.out.println("Total time for cached cls.getDeclaredConstructor().newInstance() (ms): " +  totalTime/1000000);
71

    
72
      startTime = System.nanoTime();
73
      for (int i = 0; i < iterations; i++)
74
      {
75
         for (Class<?> cls : CLASSES)
76
         {
77
            try
78
            {
79
               // EMPTY
80
            }
81
            catch (Exception e)
82
            {
83
               e.printStackTrace();
84
            }
85
         }
86
      }
87
      endTime = System.nanoTime();
88
      totalTime = (endTime - startTime);
89
      System.out.println("Total time for empty loop (ms): " +  totalTime/1000000);
90
   }
91

    
92
   private static class ClassOne { }
93
   private static class ClassTwo { }
94
   private static class ClassThree { }
95
   private static class ClassFour { }
96
   private static class ClassFive { }
97
   private static class ClassSix { }
98
   private static class ClassSeven { }
99
   private static class ClassEight { }
100
   private static class ClassNine { }
101
   private static class ClassTen { }
102
   private static class ClassEleven { }
103
   private static class ClassTwelve { }
104

    
105
   private static class Helper
106
   {
107
      private static final ClassValue<Constructor<?>> CONSTRUCTOR_CACHE = new ClassValue<>()
108
      {
109
         @Override
110
         protected Constructor<?> computeValue(Class<?> type)
111
         {
112
            try
113
            {
114
               // This block ONLY runs the very first time .get() is called for a specific class
115
               Constructor<?> constructor = type.getDeclaredConstructor();
116

    
117
               // We can set it accessible here just once, saving massive overhead later
118
               constructor.setAccessible(true);
119

    
120
               return constructor;
121
            }
122
            catch (NoSuchMethodException e)
123
            {
124
               // ClassValue requires returning a value or throwing an unchecked exception
125
               throw new RuntimeException("No no-arg constructor found for " + type.getName(), e);
126
            }
127
         }
128
      };
129

    
130
      public static <T> T createInstance(Class<T> clazz) {
131
         try {
132
            // .get(clazz) fetches from the cache, or calls computeValue() if missing
133
            Constructor<?> constructor = CONSTRUCTOR_CACHE.get(clazz);
134

    
135
            @SuppressWarnings("unchecked")
136
            T instance = (T) constructor.newInstance();
137
            return instance;
138

    
139
         } catch (Exception e) {
140
            throw new RuntimeException("Failed to instantiate " + clazz.getName(), e);
141
         }
142
      }
143
   }
144
}