Вот какой код я только что написал для обработки форматирования даты для проекта, над которым я работаю. Он имитирует функциональность форматирования даты PHP в соответствии с моими потребностями. Не стесняйтесь использовать его, он просто расширяет уже существующий объект Date (). Это может быть не самое элегантное решение, но оно работает для моих нужд.
var d = new Date();
d_string = d.format("m/d/Y h:i:s");
/**************************************
* Date class extension
*
*/
// Provide month names
Date.prototype.getMonthName = function(){
var month_names = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
return month_names[this.getMonth()];
}
// Provide month abbreviation
Date.prototype.getMonthAbbr = function(){
var month_abbrs = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
];
return month_abbrs[this.getMonth()];
}
// Provide full day of week name
Date.prototype.getDayFull = function(){
var days_full = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
return days_full[this.getDay()];
};
// Provide full day of week name
Date.prototype.getDayAbbr = function(){
var days_abbr = [
'Sun',
'Mon',
'Tue',
'Wed',
'Thur',
'Fri',
'Sat'
];
return days_abbr[this.getDay()];
};
// Provide the day of year 1-365
Date.prototype.getDayOfYear = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((this - onejan) / 86400000);
};
// Provide the day suffix (st,nd,rd,th)
Date.prototype.getDaySuffix = function() {
var d = this.getDate();
var sfx = ["th","st","nd","rd"];
var val = d%100;
return (sfx[(val-20)%10] || sfx[val] || sfx[0]);
};
// Provide Week of Year
Date.prototype.getWeekOfYear = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
}
// Provide if it is a leap year or not
Date.prototype.isLeapYear = function(){
var yr = this.getFullYear();
if ((parseInt(yr)%4) == 0){
if (parseInt(yr)%100 == 0){
if (parseInt(yr)%400 != 0){
return false;
}
if (parseInt(yr)%400 == 0){
return true;
}
}
if (parseInt(yr)%100 != 0){
return true;
}
}
if ((parseInt(yr)%4) != 0){
return false;
}
};
// Provide Number of Days in a given month
Date.prototype.getMonthDayCount = function() {
var month_day_counts = [
31,
this.isLeapYear() ? 29 : 28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
];
return month_day_counts[this.getMonth()];
}
// format provided date into this.format format
Date.prototype.format = function(dateFormat){
// break apart format string into array of characters
dateFormat = dateFormat.split("");
var date = this.getDate(),
month = this.getMonth(),
hours = this.getHours(),
minutes = this.getMinutes(),
seconds = this.getSeconds();
// get all date properties ( based on PHP date object functionality )
var date_props = {
d: date < 10 ? '0'+date : date,
D: this.getDayAbbr(),
j: this.getDate(),
l: this.getDayFull(),
S: this.getDaySuffix(),
w: this.getDay(),
z: this.getDayOfYear(),
W: this.getWeekOfYear(),
F: this.getMonthName(),
m: month < 10 ? '0'+(month+1) : month+1,
M: this.getMonthAbbr(),
n: month+1,
t: this.getMonthDayCount(),
L: this.isLeapYear() ? '1' : '0',
Y: this.getFullYear(),
y: this.getFullYear()+''.substring(2,4),
a: hours > 12 ? 'pm' : 'am',
A: hours > 12 ? 'PM' : 'AM',
g: hours % 12 > 0 ? hours % 12 : 12,
G: hours > 0 ? hours : "12",
h: hours % 12 > 0 ? hours % 12 : 12,
H: hours,
i: minutes < 10 ? '0' + minutes : minutes,
s: seconds < 10 ? '0' + seconds : seconds
};
// loop through format array of characters and add matching data else add the format character (:,/, etc.)
var date_string = "";
for(var i=0;i<dateFormat.length;i++){
var f = dateFormat[i];
if(f.match(/[a-zA-Z]/g)){
date_string += date_props[f] ? date_props[f] : '';
} else {
date_string += f;
}
}
return date_string;
};
/*
*
* END - Date class extension
*
************************************/
Я уверен, что JVM может делать некоторые трюки за кулисами, но может ли кто-нибудь помочь мне понять, что на самом деле происходит там?
blockquote>
- Массивная латентность первый вызов вызван инициализацией полной лямбда-подсистемы времени выполнения. Вы платите это только один раз за все приложение.
- При первом обращении к любому выраженному лямбда-выражению вы платите за связь этой лямбда (инициализация
invokedynamic
- После нескольких итераций вы увидите дополнительное ускорение из-за компилятора JIT, оптимизирующего ваш код восстановления.
В любом случае, чтобы избежать этого оптимизация, чтобы я мог проверить истинное время выполнения?
blockquote>Вы просите о противоречии здесь: «истинное» время выполнения - это тот, который вы получаете после разминки , когда все оптимизации были применены. Это время выполнения, которое будет испытывать фактическое приложение. Задержка первых нескольких прогонов не имеет отношения к более широкой картине, если вы не заинтересованы в производительности с одним выстрелом.
. Для исследования вы можете видеть, как ваш код ведет себя с компиляцией JIT отключен: pass
-Xint
к командеjava
. Есть еще много флагов, которые отключают различные аспекты оптимизации.
ОБНОВЛЕНИЕ: см. ответ @ Марко для объяснения начальной задержки из-за связи лямбда.
Более высокое время выполнения для первого вызова, вероятно, является результатом эффекта JIT . Короче говоря, компиляция JIT байтовых кодов в собственный машинный код возникает в первый раз, когда вы вызываете свой метод. JVM затем пытается продолжить оптимизацию, идентифицируя часто называемые (горячие) методы и повторно генерируя свои коды для повышения производительности.
Во всяком случае, чтобы избежать этой оптимизации, чтобы я мог проверить истинное время выполнения ?
blockquote>Вы можете наверняка объяснить начальную разминку JVM, исключив первые несколько результатов. Затем увеличьте количество повторных вызовов вашего метода в цикле из десятков тысяч итераций и сравните результаты.
Есть еще несколько параметров, которые вы можете захотеть добавить к вашему исполнению, чтобы помочь уменьшите шум, как описано в этой записи . Также есть некоторые полезные советы из этой почты .
истинное время выполнения
blockquote>Нет такой вещи, как «истинное время выполнения». Если вам нужно решить эту задачу только один раз, истинным временем выполнения будет время первого теста (вместе со временем для запуска самой JVM). В общем, время, затрачиваемое на выполнение данной части кода, зависит от многих вещей:
- Является ли этот фрагмент кода интерпретированным JIT-компилятором C1 или C2. Обратите внимание, что существует не только три варианта. Если вы вызываете один метод из другого, один из них может быть интерпретирован, а другой может быть скомпилирован C2.
- Для компилятора C2: как этот код был выполнен ранее, так что в профиле ветви и типа.
- Состояние сборщика мусора: прерывает ли это выполнение или нет
- Очередь компиляции: компилятор JIT компилирует другой код одновременно (что может замедлить работу вниз по исполнению текущего кода)
- Схема памяти: как объекты расположены в памяти, сколько строк кеша должно быть загружено для доступа ко всем необходимым данным.
- Состояние предсказания ветвления CPU который зависит от предыдущего исполнения кода и может увеличивать или уменьшать количество ошибочных предсказаний филиала.
И так далее и т. д. Поэтому, даже если вы измеряете что-то в изолированном контролере, это не означает, что скорость одного и того же кода в процессе производства будет одинаковой. Он может отличаться по порядку величины. Поэтому перед тем, как измерить что-то, вы должны спросить себя, почему вы хотите измерить эту вещь. Обычно вам все равно, как долго выполняется какая-то часть вашей программы. Обычно вам нравится латентность и пропускная способность всей программы. Так что профилируйте всю программу и оптимизируйте самые медленные части. Вероятно, вещь, которую вы измеряете, не самая медленная.
Java VM загружает класс в память в первый раз, когда используется класс. Таким образом, разница между 1-м и 2-м прогонами может быть вызвана загрузкой классов.