2014-09-10 35 views
0

TaggedLogger只有一個字符串字段 - tag緩存非常小的對象有什麼用處嗎?

public class TaggedLogger { 

    private final String tag; 

    public static TaggedLogger forInstance(Object instance) { 
     return new TaggedLogger(getTagOfInstance(instance)); 
    } 

    public static String getTagOfInstance(Object instance) { 
     return getTagOfClass(instance.getClass()); 
    } 

    public static TaggedLogger forClass(Class<?> someClass) { 
     return new TaggedLogger(getTagOfClass(someClass)); 
    } 

    public static String getTagOfClass(Class<?> someClass) { 
     return someClass.getName(); 
    } 

    public static TaggedLogger withTag(String tag) { 
     return new TaggedLogger(tag); 
    } 

    private TaggedLogger(String tag) { 
     this.tag = tag; 
    } 

    public void debug(Object obj) { 
     Log.d(getTag(), String.valueOf(obj)); 
    } 

    public String getTag() { 
     return tag; 
    } 

    public void exception(String message) { 
     Log.e(getTag(), String.valueOf(message)); 
    } 

    public void exception(Throwable exception) { 
     Log.e(getTag(), String.valueOf(exception.getMessage()), exception); 
    } 

    public void exception(Throwable exception, String additionalMessage) { 
     Log.e(getTag(), String.valueOf(exception.getMessage()), exception); 
     Log.e(getTag(), String.valueOf(additionalMessage)); 
    } 

    public void info(Object obj) { 
     Log.i(getTag(), String.valueOf(obj.toString())); 
    } 

} 

而且TaggedLoggers使用,以獲取緩存(或創建新的,放在緩存)TaggedLogger實例:

public class TaggedLoggers { 

    public static final TaggedLogger GLOBAL = getCachedWithTag("GLOBAL"); 

    private static final Map<String,TaggedLogger> cache = new HashMap<String, TaggedLogger>(); 

    public static TaggedLogger getCachedForInstance(Object obj) { 
     return getCachedWithTag(TaggedLogger.getTagOfInstance(obj)); 
    } 

    public static TaggedLogger getCachedForClass(Class<?> someClass) { 
     return getCachedWithTag(TaggedLogger.getTagOfClass(someClass)); 
    } 

    public static TaggedLogger getCachedWithTag(String tag) { 
     TaggedLogger logger = cache.get(tag); 
     if (logger == null) { 
      logger = TaggedLogger.withTag(tag); 
      cache.put(tag, logger); 
     } 
     return logger; 
    } 

} 

是否有TaggedLoggers類有什麼用處?

其實我經​​常使用TaggedLogger作爲標籤記錄使用參數。即:

public class FragmentUtils { 
    public static void showMessage(Fragment fragment, String message, int toastDuration) { 
     TaggedLoggers.getCachedForInstance(fragment).debug(message); 
     Context context = fragment.getActivity(); 
     if (context == null) { 
      return; 
     } 
     Toast toast = Toast.makeText(context, message, toastDuration); 
     toast.show(); 
    } 
} 

所以,緩存TaggedLogger情況下,實際上幫助我避免了很多不必要的實例。

但是,我應該這樣做嗎?

+0

你忘了問自己兩個重要問題:我有問題嗎?執行這個幫助會解決我的問題嗎? – Durandal 2014-09-10 18:40:47

回答

0

現有實例的緩存可以有很大的幫助,也可以殺死表演。

當創建一個新的實例,你必須考慮兩個因素:

  1. 的時間來設置實例本身,也就是分配RAM,初始化字段和執行構造
  2. 被垃圾所花費的時間收集器在實例無法訪問後進行清理

這在過去的JVM上過去很多時間,而不是垃圾收集器已得到改進,通常創建並拋出小型實例並不是一個大問題,因爲它之前,但仍然是成本。不知道究竟有多少Android JVM已經優化。

在這種情況下,它取決於您經常創建和拋棄這些實例的頻率。

如果不是重用他們,你必須考慮兩個因素:

  1. 查找現有實例的時間,這是一個地圖查找
  2. 即存滿實際上未使用的情況下
  3. 的RAM

所以,在這種情況下,它取決於你有多少個不同的實例。如果你將有成千上萬的TaggedLogger,那麼查看地圖並將所有這些內容保存在RAM中可能會比創建和丟棄更有害於性能。

如果TaggedLogger大概在幾百(s),那麼如果它們進入數千,那麼可能更好的緩存,那麼最好實例化並丟棄。

但是,我會問你是否需要一個TaggerLogger。如果你總是有標籤字符串,你不能簡單地調用記錄器方法,或者只在它前面有一個(甚至可能是靜態的)外觀,而不是隻包含已有的信息(標記字符串)的實例?

+0

[here](http://codereview.stackexchange.com/questions/61682/taggedlogger-log-wrapper)我說明了爲什麼我需要這個類。 – 2014-09-10 18:52:31

0

創建和垃圾收集TaggedLogger s就幾乎免費的,所以沒有實際的好處緩存他們,但因爲TaggedLoggers使用HashMap代替ConcurrentHashMap有潛力,如果從多個線程調用時,很難如果兩個線程嘗試同時調整地圖的大小,則調試直到幷包括無限循環的問題。

它幾乎沒有任何好處,會產生額外的複雜性,並可能產生問題。

參見:A Beautiful Race Condition