javascript
A single thread 、 Dynamic type language , So how do we code for the best performance ? I'll talk aboutV8
Inline optimization of the engine . With inline caching, we can write better code .
What is inline caching
Quoting the official description : inline caching (Inline caching) It is the optimization technology adopted by the runtime system of some programming languages , The earliest is Smalltalk Development . The goal of inline caching is through Remember to go directly to the call point before
To speed up method binding at run time by using the results of method queries . Inline caching is particularly useful for dynamically typed languages , Most of them ( If not all ) Method binding occurs at run time , So virtual method tables are usually not available .
- We can understand it as javascript Every time the stack is executed, an external function is called 、 Object to generate address cache records , When the next execution reaches this location, the corresponding record will be directly retrieved from the cache , Save the process of rediscovering, from speeding up program execution .
Convert to code
Analog computing logic ( Pseudo code )
In order to better present the optimization of inline cache , We make the logic of all methods of the object consistent .
let value = 0
const Calculator = {
add1(val) {
value += val
},
add2(val) {
value += val
},
add3(val) {
value += val
},
add4(val) {
value += val
},
add5(val) {
value += val
},
add6(val) {
value += val
},
add7(val) {
value += val
},
add8(val) {
value += val
},
add9(val) {
value += val
},
add10(val) {
value += val
}
}
Code that doesn't use inline optimization strategies
function notOptimization(val, type) {
Calculator[type](val) // Dynamically executing functions , The address cannot be determined at the current point
}
const CalculatorKey = Object.keys(Calculator)
console.time('notOptimization')
for(let i = 0; i < 1000000; i ++) {
const key = CalculatorKey[Math.floor(Math.random() * CalculatorKey.length)]
notOptimization(1, key)
}
console.timeEnd('notOptimization')
The above code uses hash to quickly find the corresponding function , But abandon the inline caching policy . Code 5 The first execution result , Average is 80ms about
Use inline cache policy code
function optimization(val, type) {
if (type === 'add1')
Calculator.add1(val)
else if (type === 'add2')
Calculator.add2(val)
else if (type === 'add3')
Calculator.add3(val)
else if (type === 'add4')
Calculator.add4(val)
else if (type === 'add5')
Calculator.add5(val)
else if (type === 'add6')
Calculator.add6(val)
else if (type === 'add7')
Calculator.add7(val)
else if (type === 'add8')
Calculator.add8(val)
else if (type === 'add9')
Calculator.add9(val)
else
Calculator.add10(val)
}
const CalculatorKey = Object.keys(Calculator)
console.time('optimization')
for(let i = 0; i < 1000000; i ++) {
const key = CalculatorKey[Math.floor(Math.random() * CalculatorKey.length)]
optimization(1, key)
}
console.timeEnd('optimization')
This code uses multiple layers if else Make function calls ( In order to optimize the inline cache policy , It should be used correctly switch Or array lookup ), Let's look at execution 5 Secondary results , Speed is 55~50ms
summary , So in the coding process, we try to use less dynamic call operations , But relative object property values get hashes 、 The way arrays work is much faster than if、switch Of