乐趣区

CalendargetInstance的性能问题

微信公众号:51 码农网
专业编程问答社区
www.51manong.com

Calendar.getInstance()是非常耗时的操作。需要明确的是,日历实际上不是单例。每次调用 Calendar.getInstance()都会返回一个新对象。

查看源码:

public static Calendar getInstance()
    {Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
        cal.sharedZone = true;
        return cal;
    }

再看 createCalendar 方法

    private static Calendar createCalendar(TimeZone zone,
                                           Locale aLocale)
    {
        Calendar cal = null;

        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype == null) {
            // Calendar type is not specified.
            // If the specified locale is a Thai locale,
            // returns a BuddhistCalendar instance.
            if ("th".equals(aLocale.getLanguage())
                    && ("TH".equals(aLocale.getCountry()))) {cal = new BuddhistCalendar(zone, aLocale);
            } else {cal = new GregorianCalendar(zone, aLocale);
            }
        } else if (caltype.equals("japanese")) {cal = new JapaneseImperialCalendar(zone, aLocale);
        } else if (caltype.equals("buddhist")) {cal = new BuddhistCalendar(zone, aLocale);
        } else {
            // Unsupported calendar type.
            // Use Gregorian calendar as a fallback.
            cal = new GregorianCalendar(zone, aLocale);
        }

        return cal;
    }

代码中可以清楚的看到是每次都创建的。

看看使用 System.currentTimeMillis()和 Calendar.getInstance()的性能差别

public class Test1 {public static void main(String[] args) {
       int runs = 10000;  
       long start = System.nanoTime();  
       Calendar cal = null;  
       for(int i=0;i<runs;i++)  
           cal = Calendar.getInstance();  
       long time = System.nanoTime() - start;  
       System.out.println("Calendar.getInstance() took on average"+time/runs+"ns."+cal);  

       long start2 = System.nanoTime();  
       long now = 0;  
       for(int i=0;i<runs;i++)  
           now = System.currentTimeMillis();  
       long time2 = System.nanoTime() - start2;  
       System.out.println("System.currentTimeMillis() took on average"+time2/runs+"ns."+now);  

}

结果:

Calendar.getInstance() took on average 29348 ns. java.util.GregorianCalendar[time=1569646753165,.......]
System.currentTimeMillis() took on average 89 ns. 1569646753167

微信公众号:51 码农网

退出移动版