2013-10-15 2 views
0

мне интересно, еслиПолучение производительности с помощью того же кода?

function pathJoin(uri,file){ 
    return url.format(
     url.parse(
      path.normalize(
       path.join(uri, file) 
      ).split(
       path.delimiter 
      ).join("/") 
     ) 
    ); 
} 

и

function pathJoin(uri,file){ 
    var joined_path = path.join(uri, file); 
    var normalized = path.normalize(joined_path); 
    var splitted = normalized.split(path.delimiter); 
    var joined = splitted.join("/"); 
    var parsed = url.parse(joined); 
    return url.format(parsed); 
} 

будет выполнять одинаково быстро. Нет ли штрафа за переключение из функции в функцию несколько раз?

+0

@tucuxi Поддерживает ли jsperf NodeJS? (потому что это использует путь и URL-адрес от NodeJS) – alexandernst

+3

Просто сравните его. Benchmark.js Тогда вам не нужно удивляться, и вы также можете использовать свои реальные данные. jsperf.com использует Benchmark в backgroun AFAIK и не поддерживает Node.js напрямую. @alexandernst – Nenotlep

+0

Хм, ты прав. Otoh, источник для этих функций кажется стандартным JS: https://github.com/joyent/node/blob/master/lib/path.js. Результаты для jsperf под хром (также использует V8) должны быть похожи на те, которые были испытаны в узле node.js – tucuxi

ответ

5

Примечание: path.join уже возвращает нормализованный путь. Они имеют одинаковую производительность ... И не используйте jsperf для тестирования узлов узла.

КОД

var path = require ("path"); 
var url = require ("url"); 
var speedy = require ("speedy"); 

function pathJoin(uri,file){ 
    return url.format(
     url.parse(
      path.normalize(
       path.join(uri, file) 
      ).split(
       path.delimiter 
      ).join("/") 
     ) 
    ); 
} 

function pathJoin2(uri,file){ 
    var joined_path = path.join(uri, file); 
    var normalized = path.normalize(joined_path); 
    var splitted = normalized.split(path.delimiter); 
    var joined = splitted.join("/"); 
    var parsed = url.parse(joined); 
    return url.format(parsed); 
} 

speedy.timeout (20000); 
speedy.run ({ 
    "1": function(){ 
     pathJoin ("http://www.google.com", "file"); 
    }, 
    "2": function(){ 
     pathJoin2 ("http://www.google.com", "file"); 
    } 
}) 

РЕЗУЛЬТАТ

File: t.js 

Node v0.10.20 
V8 v3.14.5.9 
Speedy v0.0.8 

Benchmarks: 2 
Timeout: 20000ms (20s 0ms) 
Samples: 3 
Total time per benchmark: ~60000ms (1m 0s 0ms) 
Total time: ~120000ms (2m 0s 0ms) 

Higher is better (ops/sec) 

1 
    50,931 ± 0.1% 
2 
    51,029 ± 0.1% 

Elapsed time: 120063ms (2m 0s 63ms) 
+0

. Мое беспокойство заключается в том, что нет никаких перегрузок вообще? Кроме того, вы можете повторно запустить это, но запустите его немного дольше. Возможно, 20 с на функцию? – alexandernst

+0

Узел работает на V8 - в соответствии с этим V8 уже делает много закулисных оптимизаций: http://stackoverflow.com/questions/4710396/squeezing-performance-out-of-v8 – tucuxi

+0

Накладных расходов нет. Обновление ответа ... с 1мин за функцию –

4

Обычно синтаксические различия не влияют на производительность. Компилятор не работает на уровне исходного кода.

На практике есть исключения, конечно. В следующем, например V8 не достаточно умны, чтобы оптимизировать последний:

function a(arg) { 
    return typeof arg === "string"; 
} 

function b(arg) { 
    var tmp = typeof arg; 
    return tmp === "string"; 
} 

Последняя будет фактически LookUp строку типа для переменной, а затем сравнить строку "string" - вместо того, чтобы проверить, если arg является строка это то, что код семантически делает. Проверьте, насколько радикально отличается сгенерированный код для функций: http://pastebin.com/h7PsV39p

Это также смешно, потому что люди оптимизируются с помощью «кеширования типа», в процессе чего они делают его намного медленнее, потому что V8 распознает только полные uncached выражения типа.

+0

Да, но я обеспокоен тем, что это не просто синтаксическая разница, а скорее перехват, так как первый способ, которым я накладываю вызовы функций. – alexandernst

+0

@alexandernst Я не читал первый код, потому что он не читается, но я предполагаю, что единственная разница - это временные переменные, и в этом случае мой ответ стоит. – Esailija

+0

Вообще говоря, нет теоретической причины для создания худшего кода во втором случае. Просто признание 'typeof v === str' значительно превосходит Crankshaft, что позволило. И когда был разработан коленчатый вал, никто не потрудился перенести распознавание образов туда, где он принадлежит. –

Смежные вопросы