2016-09-10 2 views
2

Gibt es einen Leistungsunterschied zwischen der Definition einer Funktion innerhalb der render-Funktion oder der Definition im Klassenbereich?Leistung des Funktionsausdrucks innerhalb der Renderfunktion

render Funktionsumfang:

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

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

class -umfang:

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

In beiden Fällen müssen Sie keine neue Wrapper-Funktion zum Aufrufen von 'renderItem()'; Sie können eine Referenz direkt an die Funktion übergeben. – Pointy

+0

Ja, ich weiß, aber das ist das einfache Beispiel.Manchmal muss ich es in eine Funktion einpacken, um sauber zu sehen, sonst sieht es ziemlich chaotisch aus. – kosker

+0

Was ich meinte war: '{this.props.itemList (renderItem)}' oder '{this.props.itemList (this.renderItem)}' wird äquivalent sein. Der Leistungsunterschied ist völlig trivial. – Pointy

Antwort

1

Ja, irgendwie gibt es einen Unterschied der Leistung.

Aber dieser Unterschied ist so so so minimal, dass Sie sogar bemerken oder sagen können, was der Unterschied ist.

Die Sache ist, wenn Sie die renderItem innerhalb der render Methode definieren, jedes Mal, wenn die render Methode aufgerufen wird, wird die renderItem Funktion neu erstellt werden. In der anderen Weise wird renderItem nur einmal in einem Leben definiert.

Daher können Sie denken, dass die "außerhalb" -Methode schneller sein wird. Aber die Sache ist, in der "Inside" -Methode wird die renderItem nur einmal pro Anruf erstellt. Also, wenn Sie zum Beispiel 1 Million Elemente zu rendern haben, wird der "Flaschenhals" des gesamten Prozesses die map selbst sein, und nicht die Erstellung der renderItem Methode, Gotcha?

Aber für den Test, ich baue diese Probe, um beide Methoden, insideFunction und outsideFunction zu testen. Sie können kopieren und in Ihrem Browser ausführen.

Um zu testen, Sie bench(10000) ausführen können, wie viel Zeit, um zu sehen beide Methoden mit einem Array mit 10000 Elementen (in meinem Computer, die durchschnittliche Zeit für diese Größe liegt bei etwa 0,05 bis 0,07 Sekunden.

können Sie übernehmen würde auch mehrere bench Tests ausgeführt und die Ausgabe Durchschnitt sehen, mit: nBenchs(10, 10000), 10 bench(10000) Tests laufen

Fazit. In meinem Computer, mit 1 Million Positionen Tests mit Array läuft, habe ich etwas um 7 Sekunden Durchschnitt für beide Methoden, die in den meisten Fällen mehrmals ausgeführt werden utside "Methode als halbe Sekunde schneller als" innen ". Aber denken Sie daran, wenn Sie einen Code haben, der 7 Sekunden dauert, um die Ausgabe an den Benutzer zurückzugeben, sollten Sie in anderen Alternativen nachdenken, um diesen Wert zu verringern (wie Teile des Ergebnisses zuerst und schneller angezeigt werden). Wenn Sie eine Anwendung erstellen, die mit dieser Menge an Daten umgehen kann und über starke Prozessalgorithmen verfügt (was in Web-/React-Anwendungen nicht üblich ist), dann wird jede Aktion, die Ihnen 7% der Zeit spart (halbe Sekunde von sieben) Fall) sind wertvoll.

(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

es in der Klasse-Umfang definieren wird geringfügig schneller sein, da die Funktion nur einmal erstellt werden. Wenn Sie es in der Render-Methode definieren, wird die Funktion bei jedem Aufruf der Render-Methode erstellt.

Das heißt, es ist sehr unwahrscheinlich, dass es spürbare Auswirkungen haben wird.

Verwandte Themen