isToday的高性能實現(xiàn)

fast fast fast

場景

業(yè)務(wù)中經(jīng)常需要判斷傳入的時間是不是今天徘熔,之前封裝有一個方法

public static boolean isToday(long timeMillis) {
        LocalDate now = LocalDate.now();
        LocalDate fromDate = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDate();
        return now.equals(fromDate);
}

基于LocalDate比較,具體思路是將時間戳轉(zhuǎn)換成LocalDate跪另,再基于LocalDate進行比較倔约。由于LocalDate內(nèi)部有很多隱藏邏輯啥刻,且每次調(diào)用這個方法都要創(chuàng)建兩個LocalDate對象,這段代碼只能說是正確但低效奸鸯。

我們需要一種更高效的方式,經(jīng)過一番思考和行動可帽,得出了下面這個方式

基于時間范圍比較

它有兩個特點

  1. 基于時間范圍判斷
  2. 利用線程封閉避免競態(tài)

實現(xiàn)利用了Guava的Range工具類娄涩,可以快速判斷某個值是否在給定范圍內(nèi)

public class TimeUtil {
    public static final long MILLIS_ONE_DAY = 24 * 60 * 60 * 1000;
    /**
     * 今日時間范圍,[今日開始時間戳,今日結(jié)束時間戳)
     */
    private static final ThreadLocal<Range<Long>> todayTimeRangeCache =
            ThreadLocal.withInitial(TimeUtil::createTodayTimeRange);

    /**
     * 獲取今日0點
     *
     * @return
     */
    public static long getTodayZeroMillis() {
        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    
    /**
     * 傳入時間是否屬于今天
     *
     * @param timeMillis
     * @return
     */
    public static boolean isToday(long timeMillis) {
        long now = System.currentTimeMillis();
        Range<Long> todayTimeRange = todayTimeRangeCache.get();
        if (!todayTimeRange.contains(now)) {
            Range<Long> timeRange = createTodayTimeRange();
            todayTimeRangeCache.set(timeRange);
            todayTimeRange = timeRange;
        }
        return todayTimeRange.contains(timeMillis);
    }

    private static Range<Long> createTodayTimeRange() {
        long todayStartTime = getTodayZeroMillis();
        // 如果需要考慮夏令時, 這里需要改為其他方式,邏輯于getTodayZeroMillis類似
        long todayEndTime = todayStartTime + MILLIS_ONE_DAY;
        return Range.closedOpen(todayStartTime, todayEndTime);
    }
}

新舊方案對比

方式 基于LocalDate對比 基于時間范圍對比
內(nèi)存消耗 每次調(diào)用都要創(chuàng)建兩個LocalDate對象,O(n) 每個線程僅需要創(chuàng)建一個映跟,O(1)
性能 時間戳轉(zhuǎn)換為對象蓄拣,根據(jù)當(dāng)前時間創(chuàng)建對象兜粘,均為復(fù)雜的邏輯 獲取一次當(dāng)前時間,兩到三次比較操作

isToday是一個高頻調(diào)用的方法弯蚜,對一個長期運行的項目,經(jīng)過優(yōu)化后的方式很有意義剃法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碎捺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贷洲,更是在濱河造成了極大的恐慌收厨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件优构,死亡現(xiàn)場離奇詭異诵叁,居然都是意外死亡,警方通過查閱死者的電腦和手機钦椭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門拧额,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彪腔,你說我怎么就攤上這事侥锦。” “怎么了德挣?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵恭垦,是天一觀的道長。 經(jīng)常有香客問我格嗅,道長番挺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任屯掖,我火速辦了婚禮玄柏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贴铜。我一直安慰自己禁荸,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布阀湿。 她就那樣靜靜地躺著赶熟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陷嘴。 梳的紋絲不亂的頭發(fā)上典挑,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音毅臊,去河邊找鬼。 笑死竹宋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的地技。 我是一名探鬼主播蜈七,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼莫矗!你這毒婦竟也來了飒硅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤作谚,失蹤者是張志新(化名)和其女友劉穎三娩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妹懒,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡雀监,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了眨唬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片会前。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖匾竿,靈堂內(nèi)的尸體忽然破棺而出回官,到底是詐尸還是另有隱情,我是刑警寧澤搂橙,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布歉提,位于F島的核電站,受9級特大地震影響区转,放射性物質(zhì)發(fā)生泄漏苔巨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一废离、第九天 我趴在偏房一處隱蔽的房頂上張望侄泽。 院中可真熱鬧,春花似錦蜻韭、人聲如沸悼尾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闺魏。三九已至,卻和暖如春俯画,著一層夾襖步出監(jiān)牢的瞬間析桥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泡仗,地道東北人埋虹。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像娩怎,于是被迫代替她去往敵國和親搔课。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容