2013-08-17 122 views
1

當前我正在逐行讀取數據文件。每行有格式DD/MM/YYYY HH時間戳:毫米:ss」的 我需要將其轉換成自紀元毫秒我試圖兩種方式將時間戳轉換爲自世紀以來的毫秒數

1>使用標準庫

timestamp = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH).parse(ddMMyyyy + " " + HHmmss); 
return timestamp.getTime(); 

2>這是使用喬達時庫

jiffy = format.parseMillis(ddMMyyyy + " " + HHmmss); 

分析後,我發現,方法之一是令人難以置信的昂貴,而方法二是有點比第一更便宜的一個,但仍然昂貴。第一個就是APROX CPU時間爲1600ms,第二次CPU時間爲1100ms。

問題 -

1>有沒有更好的庫,不是那麼貴?

2>如果沒有標準庫,有人可以指向我的轉換邏輯嗎?我嘗試了谷歌搜索,但沒有成功。在這個網站上有幾個公式,但他們不工作,或者讓他們打電話,然後他們不夠簡單。

感謝

**

添加的問題

**

這裏ok..adding更多細節更多細節。 測試運行是1000萬條記錄。每條線都有時間戳,自紀元以來需要將其轉換爲毫秒。

這是我嘗試的三個版本的代碼。

1>隨着喬達時間 - 迄今爲止最好的結果,但不能接受。 它在時間轉換中花費了26.9%的時間。

long jiffy = 0; 
public double getTime(String ddMMyyyy, String HHmmss) throws ParseException 
{  
    jiffy = format.parseMillis(ddMMyyyy + " " + HHmmss); 
    return jiffy/1000; 
} 

這裏是仿形 http://postimg.org/image/bvrt3esgr/

2> SimpleTimeFormat Java類。 如果我再次使用同一個對象,則需要36.1%的任務。

private long timestamp; 
public static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss",Locale.ENGLISH); 
long jiffy = 0; 

public double getTime(String ddMMyyyy, String HHmmss) throws ParseException 
{ 
    timestamp = SDF.parse(ddMMyyyy + " " + HHmmss).getTime(); 
    return timestamp; 
} 

這裏是輪廓 http://postimg.org/image/72iua8x9j/ 3>使用SimpleTimeFormat Java類。 如果創建新對象比完成此任務需要51.6%。

public long getTimei(String ddMMyyyy, String HHmmss) throws ParseException 
{ 
    timestamp = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH).parse(ddMMyyyy + " " + HHmmss); 
    return timestamp.getTime(); 
} 

這裏是輪廓 postimg.org/image/rnp2m1c2r/

現在我的問題仍然是相同的???

1>有沒有更好的庫不那麼貴?

2>如果沒有標準庫,有人可以指向我的轉換邏輯嗎?我嘗試了谷歌搜索,但沒有成功。在這個網站上有幾個公式,但他們不工作,或者讓他們打電話,然後他們不夠簡單。

+1

1100毫米有多少值? 2? 20億?無論如何,從文件中讀取行數可能會比解析日期時間長得多(讀取幾個數量級的慢),因此優化解析不會導致任何可測量的差異。 –

+0

如果你只測量一次,你的JVM就沒有預熱。做一個適當的基準。 –

+0

在下面添加更多細節.. – Nishant

回答

4

有沒有更好的庫不那麼貴?

更有可能你不應該每次都創建一個新的SimpleDateFormat,並且你忘記先溫暖代碼。我建議你在忽略前10000次運行後至少運行2秒。

或者它可能是你用(毫秒)毫秒將納秒(ns)弄糊塗了。

public static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH); 
static { 
    SDF.setTimeZone(TimeZone.getTimeZone("GMT")); 
} 

public static void main(String[] args) throws Exception { 
    String dateTime = SDF.format(new Date()); 

    long start = 0; 
    int warmup = 10000; 
    int runs = 1000000; 
    for (int i = -warmup; i < runs; i++) { 
     if (i == 0) 
      start = System.nanoTime(); 
     long time = SDF.parse(dateTime).getTime(); 
     if (time < 0) throw new AssertionError(); 
    } 
    long time = System.nanoTime() - start; 
    System.out.printf("The average time to parse the current time was %,d nano-seconds%n", time/runs); 
} 

打印

The average time to parse the current time was 1,250 nano-seconds 

如果1250毫微秒的速度不夠快,你可以寫自己的解析器。我見過的最快速度是100納秒。

0

java.time

處理這種時間轉換的現代方法是使用java.time框架。我不知道它在執行速度或垃圾生成方面的表現如何,但應該考慮到它。

java.time框架內置於Java 8及更高版本。這些課程取代了老的麻煩日期時間課程,如java.util.Date,.Calendar,& java.text.SimpleDateFormatJoda-Time團隊還建議遷移到java.time。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。

許多java.time功能被移植到Java中,並在ThreeTen-Backport中被移植到Java中,並進一步適用於Android中的ThreeTenABP

示例代碼

您的問題未能解決時區問題。所以我會假設你的輸入字符串是用於UTC,並使用Instant類。對於其他時區,請搜索堆棧溢出ZonedDateTime

Instant類表示UTC時間軸上的一個時刻,分辨率高達納秒。其toEpochMilli方法會產生一個整數(64位),用於計算自1970年以來UTC時間以來的毫秒數。請注意,這種方法涉及可能的數據丟失,因爲截斷到毫秒時,任何納秒都會被截斷。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss"); 
Instant instant = Instant.parse(yourInputStringGoesHere , formatter); 
long millisecondsSinceEpochOf1970 = instant.toEpochMilli();