JodaTime年表缓存

| 我已经根据JodaTime成功编写了一个新的年表,以代表我公司的财务日历。我参考了JodaTime源代码,以弄清楚我需要做什么。我在
BasicChronology
类中注意到的一件事是使用内部类
YearInfo
来缓存\'firstDayOfYearMillis \'-自1970-01-01(ISO)以来的毫秒数。弄清楚,如果JodaTime缓存了足够的性能瓶颈,我可能也应该将其添加到我的年表中。 但是,当我这样做时,我做了一些修改。具体来说,我将
getYearInfo
方法移到了
YearInfo
内部类中,并使其变为静态。我还将用于存储缓存值的数组也移到了内部类中。修改后的类的完整定义如下:
/**
 * Caching class for first-day-of-year millis.
 *
 */
private static final class YearInfo {

    /**
     * Cache setup for first-day-of-year milliseconds.
     */
    private static final int CACHE_SIZE = 1 << 10;
    private static final int CACHE_MASK = CACHE_SIZE - 1;
    private static transient final YearInfo[] YEAR_INFO_CACHE = new YearInfo[CACHE_SIZE];

    /**
     * Storage variables for cache.
     */
    private final int year;
    private final long firstDayMillis;
    private final boolean isLeapYear;


    /**
     * Create the stored year information.
     * 
     * @param inYear The year to store info about.
     */
    private YearInfo(final int inYear) {
        this.firstDayMillis = calculateFirstDayOfYearMillis(inYear);
        this.isLeapYear = calculateLeapYear(inYear);
        this.year = inYear;
    }

    /**
     * Get year information.
     * 
     * @param year The given year.
     * 
     * @return Year information.
     */
    private static YearInfo getYearInfo(final int year) {
        YearInfo info = YEAR_INFO_CACHE[year & CACHE_MASK];
        if (info == null || info.year != year) {
            info = new YearInfo(year);
            YEAR_INFO_CACHE[year & CACHE_MASK] = info;
        }
        return info;
    }
}
我的问题是...更改对性能或设计有何影响?我已经决定我的更改应该是线程安全的(给出有关最终成员变量的答案)。但是,为什么原始实现按原样完成,而不是这样?我知道为什么大多数静态有效使用的方法都不是(给定
BasicChronology
的子类),但是我承认我的一些OO设计知识有些生锈(过去两年来一直使用RPG )。 那么...有什么想法吗?     
已邀请:
        关于正确性,通过将YEAR_INFO_CACHE切换为静态,已经引入了较小的内存泄漏。有几种方法可以判断您的静态引用在实践中是否重要,例如根据您对数据的了解,对高速缓存将增长到多大进行近似估算;在应用程序的负载测试期间/之后分析堆;等等 您正在缓存如此小的对象,因此您可能可以毫无问题地缓存很多对象。不过,如果您发现需要限制缓存,那么您有一些选择,例如LRU缓存,基于软引用而不是直接(强)引用的缓存等。但是,我再次强调这一点在特定情况下,实施这两种方法都可能会浪费时间。 为了解释静态引用的理论问题,我将引用其他文章,而不是在此处复制它们:  1.是否为垃圾收集打开了静态字段?  2.使用太多的静态变量会导致Java内存泄漏吗? 另外,关于正确性,该代码是线程安全的,这不是因为引用是最终的,而是因为多个线程为某个缓存位置创建的YearInfo值必须相等,因此哪个缓存终止并不重要。 在设计方面,原始Joda代码中与YearInfo相关的所有内容都是私有的,因此YearInfo详细信息(包括缓存)均已很好地封装。这是一件好事。 关于性能,最好的办法是分析代码并查看正在使用大量CPU的代码。对于概要分析,您想查看在此代码中花费的时间在整个应用程序的上下文中是否重要。在负载下运行您的应用程序,并检查代码的这一部分是否重要。如果即使没有YearInfo缓存也没有在此代码中发现性能问题,则可能不是很好地利用时间来处理/担心该缓存。这是有关如何进行检查的一些信息:  1. Java应用程序的性能分析器  2.如何在Java中查找CPU密集型类? 也就是说,反之亦然-如果您的工作正在正常进行,请保持现状!     
        我写了缓存到YearInfo对象中的原始代码。您将更多逻辑封装到YearInfo类中的解决方案非常好,并且应该执行得很好。我根据意图设计了YearInfo-我想要一个粗略的数据对,仅此而已。如果Java支持结构,我将在这里使用。 至于缓存设计本身,它是基于分析结果来查看是否有影响。在大多数地方,Joda-Time会懒惰地计算字段值,并将其缓存以备后用确实提高了性能。因为此特定缓存的大小是固定的,所以它不会泄漏内存。它消耗的最大内存量是1024 YearInfo对象,大约20k字节。 Joda-Time充满了这样的专用缓存,所有这些都显示出可观的性能提升。我无法说这些技术的有效性,因为它们是针对JDK 1.3编写和测试的。     

要回复问题请先登录注册