Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Dynamische Objekterzeugung vs Singleton » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Dynamische Objekterzeugung vs Singleton
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
InformaTiger InformaTiger ist männlich
Tripel-As


images/avatars/avatar-77.gif

Dabei seit: 19.02.2013
Beiträge: 228
Herkunft: Südtirol

Dynamische Objekterzeugung vs Singleton Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Guten Abend,

ich beschäftige mich derzeit mit einer Writer und Readerlogik von einem meiner Programme und möchte hierzu gerne wissen, welche Variante schneller bzw. besser ist:

Variante 1

code:
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:
public interface Writer<T> {

    public static class Registry {

        private static final Map<Class, Writer> REGISTRY;

        static {
            REGISTRY = new HashMap<>();
            initDefaults();
        }

        private static void initDefaults(){
            register(Byte.class, new ByteWriter());
            register(Short.class, new ShortWriter());
            // [...]
            register(Object.class, new ObjectWriter());
        }

        public static <T> void register(Class<T> type, Writer<T> writer){
            REGISTRY.put(type, writer);
        }

        public static Writer<T> get(Class<T> type){
            return REGISTRY.get(type);
        }
    }

    public void write(/* whatsoever */);
}


Variante 2

code:
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:
public interface Writer<T> {

    public static class Registry {

        private static final Map<Class, Class> REGISTRY;

        static {
            REGISTRY = new HashMap<>();
            initDefaults();
        }

        private static void initDefaults(){
            register(Byte.class, ByteWriter.class);
            register(Short.class, ShortWriter.class);
            // [...]
            register(Object.class, ObjectWriter.class);
        }

        public static <T> void register(Class<T> type, Class<Writer<T>> writer){
            REGISTRY.put(type, writer);
        }

        public static Writer<T> get(Class<T> type) throws Exception{
            Class<Writer<T>> writerType = REGISTRY.get(type);

            if (writerType == null){
                throw new NullPointerException("No writer registered for class " + type.getName());
            }
            return writerType.newInstance();
        }
    }

    public void write(/* whatsoever */);
}


Ich kann mir sicherlich vorstellen, dass beide ihre Vor- und Nachteile haben. Ersteres greift automatisch immer auf dasselbe Writer-Objekt zu und spart deshalb den Zeitaufwand ein neues Objekt anzulegen. Nachteil klarerweise ist der dadurch permanent belegte Speicher, der nicht anderweitig verwendbar ist. Soweit ich informiert bin und hier zu finden ist, verbraucht ein gängiges Java-Objekt ohne Membervariablen 8 Bytes an Speicher - was an sich ja nicht so viel wäre.
Zweiteres hingegen muss auch eine Instanz der ReflectionKlasse halten und gegebenenfalls eine Objektinstanz anlegen falls ein get-Aufruf erfolgt. Leider habe ich keinerlei Anhaltspunkt, wie aufwendig ein Aufruf der newInstance Methode im Vergleich zur gängigen Instanzierung ist. Desweiteren habe ich ebenso keine Ahnung wie viel Speicher eine ReflectionClass verbraucht.

Könnt ihr mir diesbezüglich ein paar Tipps geben?
Danke schon mal im voraus.

smile

Mit freundlichen Grüßen
InformaTiger

__________________
Why do Java developers wear glasses? Because they can't C#
24.11.2017 22:22 InformaTiger ist offline Beiträge von InformaTiger suchen Nehmen Sie InformaTiger in Ihre Freundesliste auf
InformaTiger InformaTiger ist männlich
Tripel-As


images/avatars/avatar-77.gif

Dabei seit: 19.02.2013
Beiträge: 228
Herkunft: Südtirol

RE: Dynamische Objekterzeugung vs Singleton Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Um mir hier mal selbst eine Antwort geben zu können, habe ich mir einen kleinen Test geschrieben der wie folgt aussieht:

code:
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:
package org.performance.test;

import java.util.ArrayList;
import org.performance.test.entity.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PerformanceTest {

    public static void main(String[] args) throws ReflectiveOperationException {        
        testMap1();        
        testMap2();
    }
    
    public static void testMap1() throws InstantiationException, IllegalAccessException{
        System.out.println("Type 1 test");
        System.out.println("Map<Class, Class<? extends Agent>");
        System.out.println("-----------");
        
        gc();
        
        long mem = Runtime.getRuntime().freeMemory();
        System.out.println("Memory before map creation: " +  mem);
        
        Map<Class, Class<? extends Agent>> var1 = constructType1();
        
        gc();
        
        long mem2 = Runtime.getRuntime().freeMemory();
        
        System.out.println("Memory after map creation: " + mem2);
        System.out.println("Memory delta: " + (mem - mem2));
        System.out.println("Entry size: " + ((mem - mem2) / var1.size()));
        
        List<Long> timespan = new ArrayList<>();        
        for (int i = 0; i < 1000; i++){
            long start = System.nanoTime();
            
            Class<? extends Agent> type = var1.get(Boolean.class);
            Agent agent = type.newInstance();
            
            agent.doAction(false);
            
            long end = System.nanoTime();            
            timespan.add(end - start);
        }
        double avg = timespan.stream().mapToLong(v -> v).average().getAsDouble();
        System.out.println("\nAvg Performance: " + avg);
    }
    
    public static void testMap2(){    
        System.out.println("\nType 2 test");
        System.out.println("Map<Class, Agent>");
        System.out.println("-----------");
        
        gc();
        
        long mem = Runtime.getRuntime().freeMemory();
        System.out.println("Memory before map creation: " + mem);

        Map<Class, Agent> var2 = constructType2();        
        
        gc();
        
        long mem2 = Runtime.getRuntime().freeMemory();
        
        System.out.println("Memory after map creation: " + mem2);
        System.out.println("Memory delta: " + (mem - mem2));
        System.out.println("Entry size: " +  ((mem - mem2) / var2.size()));
        
        List<Long> timespan = new ArrayList<>();
        for (int i = 0; i < 1000; i++){
            long start = System.nanoTime();
            
            Agent agent = var2.get(Boolean.class);
            agent.doAction(false);
            
            long end = System.nanoTime();            
            timespan.add(end - start);
        }
        double avg = timespan.stream().mapToLong(v -> v).average().getAsDouble();
        System.out.println("\nAvg Performance: " + avg);
    }
    
    public static Map<Class, Class<? extends Agent>> constructType1(){
        Map<Class, Class<? extends Agent>> map = new HashMap<>();
        map.put(Boolean.class, BooleanAgent.class);
        map.put(Double.class, DoubleAgent.class);
        map.put(Float.class, FloatAgent.class);
        map.put(Integer.class, IntegerAgent.class);
        map.put(Object.class, ObjectAgent.class);
        map.put(Short.class, ShortAgent.class);
        map.put(String.class, StringAgent.class);        
        
        return map;
    }
    
    public static Map<Class, Agent> constructType2(){
        Map<Class, Agent> map = new HashMap<>();
        map.put(Boolean.class, new BooleanAgent());
        map.put(Double.class, new DoubleAgent());
        map.put(Float.class, new FloatAgent());
        map.put(Integer.class, new IntegerAgent());
        map.put(Object.class, new ObjectAgent());
        map.put(Short.class, new ShortAgent());
        map.put(String.class, new StringAgent());
        
        return map;
    }
    
    public static void gc(){
        Runtime rt = Runtime.getRuntime();
        
        for (int i = 0; i < 500; i++){
            rt.gc();
        }
    }    
}


Der Test gibt dann folgendes aus:

Zitat:
Type 1 test
Map<Class, Class<? extends Agent>
-----------
Memory before map creation: 64202408
Memory after map creation: 64197200
Memory delta: 5208
Entry size: 744

Avg Performance: 8897.376

Type 2 test
Map<Class, Agent>
-----------
Memory before map creation: 63926560
Memory after map creation: 63926192
Memory delta: 368
Entry size: 52

Avg Performance: 750.258


Auch bei mehrmaligem ausführen verändern sich die Ergebnisse kaum, weshalb ich zum Ergebnis kommen kann, dass die zweite Variante um einiges schneller und auch mit wesentlich weniger Speicheraufwand läuft.

smile

Mit freundlichen Grüßen
InformaTiger

__________________
Why do Java developers wear glasses? Because they can't C#
27.11.2017 18:04 InformaTiger ist offline Beiträge von InformaTiger suchen Nehmen Sie InformaTiger in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Dynamische Objekterzeugung vs Singleton