2016-09-10 3 views
2

Есть ли разница в производительности между определением функции внутри функции render или ее определением в классе?Выполнение выражения функции внутри функции рендеринга

render область видимости функции:

render() { 
    const renderItem = (item) => (<li>{item.name}</li>); 

    return (<ul> 
    {this.props.itemList.map((item) => renderItem(item))} 
    </ul>); 
} 

class область применения:

export default class MyComponent extends React.Component { 
    const renderItem = (item) => (<li>{item.name}</li>); 

    render() { 
    return (<ul> 
     {this.props.itemList.map((item) => this.renderItem(item))} 
    </ul>); 
    } 

} 
+0

В обоих случаях вам не нужно создавать новую функцию-обертку для вызова 'renderItem()'; вы можете передать ссылку на функцию напрямую. – Pointy

+0

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

+0

Что я имел в виду: '{this.props.itemList (renderItem)}' или '{this.props.itemList (this.renderItem)}' будет эквивалентным. Разница в производительности абсолютно тривиальна. – Pointy

ответ

1

Да, как-то есть разница в производительности.

Но это различие настолько настолько минимальное, что вы даже можете заметить или рассказать, в чем разница.

Дело в том, когда вы определяете renderItem внутри метода render, каждый раз, когда вызывается метод render, функция renderItem будет воссоздан. В другом случае renderItem определяется только один раз в жизни.

Из-за этого вы можете думать, что метод «снаружи» будет быстрее. Но дело в том, что в методе «внутри» renderItem будет создан только один раз за вызов. Так что, если у вас есть, например, 1 миллион элементов для рендеринга, «узким местом» всего процесса будет сам map, а не создание метода renderItem, gotcha?

Но для испытания я строю этот образец, чтобы проверить оба метода: insideFunction и outsideFunction. Вы можете копировать и запускать в своем браузере.

Чтобы проверить, вы можете запустить bench(10000), чтобы увидеть, сколько времени оба метода взять с массивом 10000 элементов (в моем компьютере, среднее время для этого размера составляет около 0,05 ~ 0,07 сек.

Вы можете также запустить несколько bench тестов и посмотреть средний выходную, с: nBenchs(10, 10000), запустить 10 bench(10000) тестов

Заключения:. В моем компьютере, выполнение тестов с массивом с 1 миллион позиций, я получил что-то около 7 секунд среднего для оба метода. Выполняя это несколько раз, в большинстве случаев, «o укрытый "метод наполовину быстрее, чем" внутри ". Но имейте это в виду, если у вас есть код, который занимает 7 секунд, чтобы вернуть результат пользователю, вы должны начать думать о других альтернативах, чтобы уменьшить это значение (например, сначала показывать части результата и быстрее). Если вы создаете приложение, которое обрабатывает данные amout, и у вас есть сложные алгоритмы выполнения (что не является обычным явлением в приложениях для веб-приложений), то каждое действие, которое сэкономит вам 7% времени (половина секунды из семи, в этом случай) являются драгоценными.

(function() { 
    function renderItem(text) { 
    let item = document.createElement('li'); 
    item.innerHTML = text; 

    return item; 
    } 
    function outsideFunction(array) { 
    return array.map(renderItem); 
    } 

    // exponse outsideFunction 
    window.outsideFunction = outsideFunction; 
})(); 

(function() { 
    function insideFunction(array) { 
    function renderItem(text) { 
     let item = document.createElement('li'); 
     item.innerHTML = text; 

     return item; 
    } 

    return array.map(renderItem); 
    } 

    // exponse insideFunction 
    window.insideFunction = insideFunction; 
})(); 

// just build an array with n elements 
function buildArray(n) { 
    let testArray = []; 
    for(let i=0; i<n; i++) { 
    testArray.push(`Text with index ${i}`); 
    } 

    return testArray; 
} 

// run nb test benchs with an array with n elements 
function nBenchs(nb, n) { 
    let Ocount = 0, Icount = 0; 
    let result; 

    for(let i=0; i<nb; i++) { 
    result = bench(n); 

    Ocount += result.Oend; 
    Icount += result.Iend; 
    } 

    // output the average 
    console.log(`outsideFunction average: ${Ocount/(nb*1000)} seconds`); 
    console.log(`insideFunction average: ${Icount/(nb*1000)} seconds`); 
} 

// run a test bench with an array with n elements 
function bench(n) { 
    n = n || 100; 

    let testArray = buildArray(n); 
    let start, Oend, Iend; 

    start = new Date(); 
    outsideFunction(testArray); 
    Oend = ((new Date())-start); 

    console.log(`outsideFunction: ${Oend/1000} secods`); 

    start = new Date(); 
    insideFunction(testArray); 
    Iend = ((new Date())-start); 

    console.log(`insideFunction: ${Iend/1000} secods`); 

    return { Oend, Iend }; 
} 
0

Определение его в классе-объем будет немного быстрее, потому что функция будет создана только один раз. Если вы определяете его в методе рендеринга, функция будет создаваться каждый раз, когда вызывается метод render.

Это очень маловероятно, что это будет иметь заметное влияние.

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