perf: optimize flip function
#9026
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Before submitting the PR, please make sure you do the following
Sorry for my English. Let's see how long this code is executed and what byte-code it will output:
Time - 1.585s
V8 byte code for loop function:
LdaZero
Star0
LdaSmi.ExtraWide [1000000000]
TestLessThanOrEqual r0, [0]
JumpIfFalse [165] (0x3491efd187ae @ 176)
LdaImmutableCurrentContextSlot [2]
ThrowReferenceErrorIfHole [0]
Star3
GetIterator r3, [1], [3]
Star5
GetNamedProperty r5, [1], [5]
Star4
LdaFalse
Star6
Mov , r9
Ldar r6
JumpIfToBooleanTrue [33] (0x3491efd18742 @ 68)
LdaTrue
Star6
CallProperty0 r4, r5, [11]
Star10
JumpIfJSReceiver [7] (0x3491efd18731 @ 51)
CallRuntime [ThrowIteratorResultNotAnObject], r10-r10
GetNamedProperty r10, [2], [9]
JumpIfToBooleanTrue [13] (0x3491efd18742 @ 68)
GetNamedProperty r10, [3], [7]
Star10
LdaFalse
Star6
Ldar r10
Jump [3] (0x3491efd18743 @ 69)
LdaUndefined
Star1
Ldar r6
JumpIfToBooleanTrue [33] (0x3491efd18767 @ 105)
LdaTrue
Star6
CallProperty0 r4, r5, [13]
Star10
JumpIfJSReceiver [7] (0x3491efd18756 @ 88)
CallRuntime [ThrowIteratorResultNotAnObject], r10-r10
GetNamedProperty r10, [2], [9]
JumpIfToBooleanTrue [13] (0x3491efd18767 @ 105)
GetNamedProperty r10, [3], [7]
Star10
LdaFalse
Star6
Ldar r10
Jump [3] (0x3491efd18768 @ 106)
LdaUndefined
Star2
LdaSmi [-1]
Star8
Star7
Jump [5] (0x3491efd18772 @ 116)
Star8
LdaZero
Star7
LdaTheHole
SetPendingMessage
Star9
Ldar r6
JumpIfToBooleanTrue [35] (0x3491efd1879a @ 156)
Mov , r11
GetNamedProperty r5, [4], [15]
JumpIfUndefinedOrNull [26] (0x3491efd1879a @ 156)
Star12
CallProperty0 r12, r5, [17]
JumpIfJSReceiver [19] (0x3491efd1879a @ 156)
Star13
CallRuntime [ThrowIteratorResultNotAnObject], r13-r13
Jump [11] (0x3491efd1879a @ 156)
Star11
LdaZero
TestReferenceEqual r7
JumpIfTrue [5] (0x3491efd1879a @ 156)
Ldar r11
ReThrow
Ldar r9
SetPendingMessage
LdaZero
TestReferenceEqual r7
JumpIfFalse [5] (0x3491efd187a5 @ 167)
Ldar r8
ReThrow
Ldar r0
Inc [19]
Star0
JumpLoop [170], [0], [20] (0x3491efd18700 @ 2)
LdaUndefined
Return
Just an awful lot, isn't it? How could we optimize these instructions for V8? Everything is pretty simple. Many people forget that an array is the most common object, and destructuring can be done using { } and not [ ].
By doing this, we will significantly simplify life in V8, since we will tell him exactly from which indices to get values.
Now let's take a look at the optimized version of working on indexes:
Time - 480.689ms - Code is ~4 times faster
V8 byte code for loop function:
LdaZero
Star0
LdaSmi.ExtraWide [1000000000]
TestLessThanOrEqual r0, [0]
JumpIfFalse [29] (0x70000186d6 @ 40)
LdaImmutableCurrentContextSlot [2]
ThrowReferenceErrorIfHole [0]
Star3
LdaZero
Star4
GetKeyedProperty r3, [1]
Star1
LdaSmi [1]
Star4
GetKeyedProperty r3, [3]
Star2
Ldar r0
Inc [5]
Star0
JumpLoop [34], [0], [6] (0x70000186b0 @ 2)
LdaUndefined
Return
I think it is obvious that the code above for V8 is much easier to process and optimize.
feat:,fix:,chore:, ordocs:.Tests and linting
pnpm testand lint the project withpnpm lint