2013-08-17 4 views
1

В настоящее время я читаю файл данных по строкам. Каждая строка имеет метку времени в формате дд/мм/гггг чч: мм:. Сс» мне нужно преобразовать это в милли секунд с начала отсчета я попробовал два способаПреобразование временной метки в миллисекунд с эпохи

1> Использование стандартной библиотеки

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

2> Это использование Joda-Time Library

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

После профилирования, я обнаружил, что метод один невероятно дорого, тогда как методы два немного дешевле, чем первый, но все еще дорого. первые из них принимает Aprox 1600 мс процессорного времени и второй занимает 1100 мс процессорного времени.

Вопросы -

1> Есть ли лучше библиотека, которая не стоит так дорого?

2> Если нет стандартной библиотеки, может ли кто-нибудь указать мне на логику преобразования? Я пробовал искать, но ничего не добился. На этом сайте есть несколько формул, но они не работают или позволяют назвать это, но они недостаточно просты.

Благодаря

**

Добавление большего количества деталей на вопрос

**

ok..adding подробнее здесь. Испытательный прогон рассчитан на 10 миллионов записей. Каждая строка имеет временную метку, которая должна быть преобразована в миллисекунд с эпохи.

Вот три версии кода, которые я пробовал.

1> С Joda-Time - Пока лучший результат, но неприемлем. Он тратит 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? 2 миллиарда? Чтение строк из файла, вероятно, будет намного дольше (читайте на несколько порядков медленнее), чем в любом случае обрабатывать даты, поэтому оптимизация синтаксического анализа не приведет к какой-либо измеримой разнице. –

+0

Если вы только измеряете один раз, ваша JVM не нагревается.Сделайте правильный тест. –

+0

добавив подробнее подробнее .. – Nishant

ответ

4

Есть ли лучше библиотека, которая не так дорого?

Скорее всего, вы не должны создавать новый SimpleDateFormat каждый раз, и вы забыли сначала разогреть код. Я предлагаю вам запустить тест не менее 2 секунд после игнорирования первых 10 000 прогонов.

Возможно, вы смутили (ns) nano-seconds с (мс) миллисекундами.

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.SimpleDateFormat. Команда Joda-Time также рекомендует перейти на java.time.

Чтобы узнать больше, см. Oracle Tutorial. И поиск Stack Overflow для многих примеров и объяснений.

Большая часть функциональности java.time портирована на Java 6 & 7 в ThreeTen-Backport и далее адаптирована для Android в ThreeTenABP.

Пример кода

Ваш вопрос не решает вопрос о временной зоне. Поэтому я предполагаю, что ваши входные строки были предназначены для UTC и используют класс Instant. Для других часовых поясов выполните поиск переполнения стека для ZonedDateTime.

Класс Instant представляет момент на шкале времени в UTC с разрешением до наносекунд. Его метод toEpochMilli производит целочисленное число long (64-разрядное), подсчитывающее количество миллисекунд с первого момента 1970 года в формате UTC. Помните, что этот метод предполагает возможную потерю данных, так как любые наносекунды теряются при усечении до миллисекунд.

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