let page = elem.children[1].children[0].children[0].children[0];
//аналогичный поезд может быть из .parentNode
илиlet page = document.querySelector('.page'); // То же самое
let container;
let root;
const arr = [];
function genHtml() {
const ch1 = document.createElement('div');
const ch2 = document.createElement('div');
const ch3 = document.createElement('div');
container = ch3;
root = ch1;
ch2.appendChild(ch3);
ch1.appendChild(ch2);
for (let i = 0; i < 10000; i++) {
const el = document.createElement('div');
el.classList.add(`child-${i}`);
el.textContent = `child-${i}`;
container.appendChild(el);
}
document.body.appendChild(root);
}
function testChild() {
const start = performance.now();
for (let i = 0; i < 10000; i++) {
let page = root.children[0].children[0].children[i];
arr.push(page);
}
console.log('testChild:', performance.now() - start);
}
function testSelector() {
const start = performance.now();
for (let i = 0; i < 10000; i++) {
let page = document.querySelector('child-' + i);
arr.push(page);
}
console.log('testSelector:', performance.now() - start);
}
genHtml();
testChild();
testSelector();
и что сложного "раскрутить" хеш? Это практически обращение по индексу.
Многовато?
А что там с коллизиями на такой длине?
дело в том, что если хэш влазит в регистр, то он полностью эквивалентен индексу.
И что вас смущает?
package main
import ("fmt")
var adata []int
var bdata map[int]int
func aFunc(i int) int {
return adata[i]
}
func bFunc(i int) int {
return bdata[i]
}
func main() {
bdata := make(map[int]int)
for i:= 0; i<10; i++ {
adata = append(adata, i)
bdata[i] = i
}
fmt.Println(aFunc(5))
fmt.Println(bFunc(5))
}
"".aFunc STEXT nosplit size=58 args=0x10 locals=0x8
0x0000 00000 (aaa.go:8) TEXT "".aFunc(SB), NOSPLIT|ABIInternal, $8-16
0x0000 00000 (aaa.go:8) SUBQ $8, SP
0x0004 00004 (aaa.go:8) MOVQ BP, (SP)
0x0008 00008 (aaa.go:8) LEAQ (SP), BP
0x000c 00012 (aaa.go:8) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x000c 00012 (aaa.go:8) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x000c 00012 (aaa.go:8) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
0x000c 00012 (aaa.go:9) PCDATA $2, $1
0x000c 00012 (aaa.go:9) PCDATA $0, $0
0x000c 00012 (aaa.go:9) MOVQ "".adata(SB), AX
0x0013 00019 (aaa.go:9) MOVQ "".i+16(SP), CX
0x0018 00024 (aaa.go:9) CMPQ "".adata+8(SB), CX
0x001f 00031 (aaa.go:9) JLS 51
0x0021 00033 (aaa.go:9) PCDATA $2, $0
0x0021 00033 (aaa.go:9) MOVQ (AX)(CX*8), AX
0x0025 00037 (aaa.go:9) MOVQ AX, "".~r1+24(SP)
0x002a 00042 (aaa.go:9) MOVQ (SP), BP
0x002e 00046 (aaa.go:9) ADDQ $8, SP
0x0032 00050 (aaa.go:9) RET
0x0033 00051 (aaa.go:9) CALL runtime.panicindex(SB)
0x0038 00056 (aaa.go:9) UNDEF
0x0000 48 83 ec 08 48 89 2c 24 48 8d 2c 24 48 8b 05 00 H...H.,$H.,$H...
0x0010 00 00 00 48 8b 4c 24 10 48 39 0d 00 00 00 00 76 ...H.L$.H9.....v
0x0020 12 48 8b 04 c8 48 89 44 24 18 48 8b 2c 24 48 83 .H...H.D$.H.,$H.
0x0030 c4 08 c3 e8 00 00 00 00 0f 0b ..........
rel 15+4 t=15 "".adata+0
rel 27+4 t=15 "".adata+8
rel 52+4 t=8 runtime.panicindex+0
"".bFunc STEXT size=104 args=0x10 locals=0x28
0x0000 00000 (aaa.go:12) TEXT "".bFunc(SB), ABIInternal, $40-16
0x0000 00000 (aaa.go:12) MOVQ TLS, CX
0x0009 00009 (aaa.go:12) MOVQ (CX)(TLS*2), CX
0x0010 00016 (aaa.go:12) CMPQ SP, 16(CX)
0x0014 00020 (aaa.go:12) JLS 97
0x0016 00022 (aaa.go:12) SUBQ $40, SP
0x001a 00026 (aaa.go:12) MOVQ BP, 32(SP)
0x001f 00031 (aaa.go:12) LEAQ 32(SP), BP
0x0024 00036 (aaa.go:12) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0024 00036 (aaa.go:12) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0024 00036 (aaa.go:12) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
0x0024 00036 (aaa.go:13) PCDATA $2, $1
0x0024 00036 (aaa.go:13) PCDATA $0, $0
0x0024 00036 (aaa.go:13) LEAQ type.map[int]int(SB), AX
0x002b 00043 (aaa.go:13) PCDATA $2, $0
0x002b 00043 (aaa.go:13) MOVQ AX, (SP)
0x002f 00047 (aaa.go:13) PCDATA $2, $1
0x002f 00047 (aaa.go:13) MOVQ "".bdata(SB), AX
0x0036 00054 (aaa.go:13) PCDATA $2, $0
0x0036 00054 (aaa.go:13) MOVQ AX, 8(SP)
0x003b 00059 (aaa.go:13) MOVQ "".i+48(SP), AX
0x0040 00064 (aaa.go:13) MOVQ AX, 16(SP)
0x0045 00069 (aaa.go:13) CALL runtime.mapaccess1_fast64(SB)
0x004a 00074 (aaa.go:13) PCDATA $2, $1
0x004a 00074 (aaa.go:13) MOVQ 24(SP), AX
0x004f 00079 (aaa.go:13) PCDATA $2, $0
0x004f 00079 (aaa.go:13) MOVQ (AX), AX
0x0052 00082 (aaa.go:13) MOVQ AX, "".~r1+56(SP)
0x0057 00087 (aaa.go:13) MOVQ 32(SP), BP
0x005c 00092 (aaa.go:13) ADDQ $40, SP
0x0060 00096 (aaa.go:13) RET
0x0061 00097 (aaa.go:13) NOP
0x0061 00097 (aaa.go:12) PCDATA $0, $-1
0x0061 00097 (aaa.go:12) PCDATA $2, $-1
0x0061 00097 (aaa.go:12) CALL runtime.morestack_noctxt(SB)
0x0066 00102 (aaa.go:12) JMP 0
0x0000 65 48 8b 0c 25 28 00 00 00 48 8b 89 00 00 00 00 eH..%(...H......
0x0010 48 3b 61 10 76 4b 48 83 ec 28 48 89 6c 24 20 48 H;a.vKH..(H.l$ H
0x0020 8d 6c 24 20 48 8d 05 00 00 00 00 48 89 04 24 48 .l$ H......H..$H
0x0030 8b 05 00 00 00 00 48 89 44 24 08 48 8b 44 24 30 ......H.D$.H.D$0
0x0040 48 89 44 24 10 e8 00 00 00 00 48 8b 44 24 18 48 H.D$......H.D$.H
0x0050 8b 00 48 89 44 24 38 48 8b 6c 24 20 48 83 c4 28 ..H.D$8H.l$ H..(
0x0060 c3 e8 00 00 00 00 eb 98 ........
rel 12+4 t=16 TLS+0
rel 39+4 t=15 type.map[int]int+0
rel 50+4 t=15 "".bdata+0
rel 70+4 t=8 runtime.mapaccess1_fast64+0
rel 98+4 t=8 runtime.morestack_noctxt+0
func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
if raceenabled && h != nil {
callerpc := getcallerpc()
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
}
if h == nil || h.count == 0 {
return unsafe.Pointer(&zeroVal[0])
}
if h.flags&hashWriting != 0 {
throw("concurrent map read and map write")
}
var b *bmap
if h.B == 0 {
// One-bucket table. No need to hash.
b = (*bmap)(h.buckets)
} else {
hash := t.key.alg.hash(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
m := bucketMask(h.B)
b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
if c := h.oldbuckets; c != nil {
if !h.sameSizeGrow() {
// There used to be half as many buckets; mask down one more power of two.
m >>= 1
}
oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
if !evacuated(oldb) {
b = oldb
}
}
}
for ; b != nil; b = b.overflow(t) {
for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
if *(*uint64)(k) == key && !isEmpty(b.tophash[i]) {
return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
}
}
}
return unsafe.Pointer(&zeroVal[0])
}
start = Date.now();
for (let i = 0; i < 10000; i++) {
let el = document.querySelector(".layout__body");
}
console.log(Date.now() - start);