Какой класс загружается при создании потока с выражением лямбда? [Дубликат]

Вот какой код я только что написал для обработки форматирования даты для проекта, над которым я работаю. Он имитирует функциональность форматирования даты 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
 * 
 ************************************/
7
задан Tagir Valeev 16 August 2015 в 16:34
поделиться

4 ответа

Я уверен, что JVM может делать некоторые трюки за кулисами, но может ли кто-нибудь помочь мне понять, что на самом деле происходит там?

  1. Массивная латентность первый вызов вызван инициализацией полной лямбда-подсистемы времени выполнения. Вы платите это только один раз за все приложение.
  2. При первом обращении к любому выраженному лямбда-выражению вы платите за связь этой лямбда (инициализация invokedynamic
  3. После нескольких итераций вы увидите дополнительное ускорение из-за компилятора JIT, оптимизирующего ваш код восстановления.

В любом случае, чтобы избежать этого оптимизация, чтобы я мог проверить истинное время выполнения?

Вы просите о противоречии здесь: «истинное» время выполнения - это тот, который вы получаете после разминки , когда все оптимизации были применены. Это время выполнения, которое будет испытывать фактическое приложение. Задержка первых нескольких прогонов не имеет отношения к более широкой картине, если вы не заинтересованы в производительности с одним выстрелом.

. Для исследования вы можете видеть, как ваш код ведет себя с компиляцией JIT отключен: pass -Xint к команде java. Есть еще много флагов, которые отключают различные аспекты оптимизации.

7
ответ дан Marko Topolnik 1 September 2018 в 07:19
поделиться

ОБНОВЛЕНИЕ: см. ответ @ Марко для объяснения начальной задержки из-за связи лямбда.


Более высокое время выполнения для первого вызова, вероятно, является результатом эффекта JIT . Короче говоря, компиляция JIT байтовых кодов в собственный машинный код возникает в первый раз, когда вы вызываете свой метод. JVM затем пытается продолжить оптимизацию, идентифицируя часто называемые (горячие) методы и повторно генерируя свои коды для повышения производительности.

Во всяком случае, чтобы избежать этой оптимизации, чтобы я мог проверить истинное время выполнения ?

Вы можете наверняка объяснить начальную разминку JVM, исключив первые несколько результатов. Затем увеличьте количество повторных вызовов вашего метода в цикле из десятков тысяч итераций и сравните результаты.

Есть еще несколько параметров, которые вы можете захотеть добавить к вашему исполнению, чтобы помочь уменьшите шум, как описано в этой записи . Также есть некоторые полезные советы из этой почты .

3
ответ дан Community 1 September 2018 в 07:19
поделиться

истинное время выполнения

Нет такой вещи, как «истинное время выполнения». Если вам нужно решить эту задачу только один раз, истинным временем выполнения будет время первого теста (вместе со временем для запуска самой JVM). В общем, время, затрачиваемое на выполнение данной части кода, зависит от многих вещей:

  • Является ли этот фрагмент кода интерпретированным JIT-компилятором C1 или C2. Обратите внимание, что существует не только три варианта. Если вы вызываете один метод из другого, один из них может быть интерпретирован, а другой может быть скомпилирован C2.
  • Для компилятора C2: как этот код был выполнен ранее, так что в профиле ветви и типа.
  • Состояние сборщика мусора: прерывает ли это выполнение или нет
  • Очередь компиляции: компилятор JIT компилирует другой код одновременно (что может замедлить работу вниз по исполнению текущего кода)
  • Схема памяти: как объекты расположены в памяти, сколько строк кеша должно быть загружено для доступа ко всем необходимым данным.
  • Состояние предсказания ветвления CPU который зависит от предыдущего исполнения кода и может увеличивать или уменьшать количество ошибочных предсказаний филиала.

И так далее и т. д. Поэтому, даже если вы измеряете что-то в изолированном контролере, это не означает, что скорость одного и того же кода в процессе производства будет одинаковой. Он может отличаться по порядку величины. Поэтому перед тем, как измерить что-то, вы должны спросить себя, почему вы хотите измерить эту вещь. Обычно вам все равно, как долго выполняется какая-то часть вашей программы. Обычно вам нравится латентность и пропускная способность всей программы. Так что профилируйте всю программу и оптимизируйте самые медленные части. Вероятно, вещь, которую вы измеряете, не самая медленная.

3
ответ дан Tagir Valeev 1 September 2018 в 07:19
поделиться

Java VM загружает класс в память в первый раз, когда используется класс. Таким образом, разница между 1-м и 2-м прогонами может быть вызвана загрузкой классов.

1
ответ дан tkob 1 September 2018 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: