Medida la ganancia del PGO ayer: -9,4% en una página de DOM/maquetación y -1,0% en 3d-raytrace de SunSpider. La razón de la diferencia es que un benchmark JIT-bound es casi CIEGO al PGO: el bucle caliente no lo ejecuta el C++ de SpiderMonkey sino el código máquina que el JIT emite en runtime, y el PGO optimiza el intérprete, el GC y el propio JIT — no lo que el JIT produce. El corpus de Mozilla está dominado en número de páginas por SunSpider, o sea que entrenaba mucho justo donde el PGO menos rinde. Estas diez ejercitan el camino que sí es C++ de punta a punta: flex flexbox anidado, wrap, alineaciones rejilla CSS Grid: pistas, áreas nombradas, auto-fit tablas tablas grandes con table-layout FIJO y AUTO (dos algoritmos) texto columnas, shaping, reflujo por cambio de ancho selectores DOM profundo contra 600 reglas, muchas que NO casan pintado degradados, sombras, opacidad, mix-blend-mode transformar transforms y contextos de apilamiento svg paths, degradados, clip desbordes overflow anidado, position:sticky, scroll programático reflujo layout thrashing: leer y escribir geometría alternadamente Reglas que cumplen todas, y no son de estilo: · DETERMINISTAS (LCG propio, ni Math.random ni Date ni red) — dos corridas hacen lo mismo, así que dos perfiles difieren por el timing de los contadores y no por haber visitado caminos distintos. · AUTOCONTENIDAS — el perfilado corre sin red. · NUESTRAS — nada de páginas ajenas capturadas, que traerían licencia y fragilidad. · ACOTADAS — 16 a 32 s cada una; el perfilado arranca un navegador POR PÁGINA. Validadas las diez contra el firefox sellado: todas renderizan y producen captura. `flex` hubo que acortarla de 40 a 12 cajas raíz: con 40 la página medía 68.241 px de alto y la captura moría con «Failed to allocate a surface due to invalid size». El layout ocurría igual, pero sin captura no se ejercita el pintado, que es justo la mitad que se venía a entrenar.
36 lines
1.7 KiB
HTML
36 lines
1.7 KiB
HTML
<!doctype html><meta charset=utf-8><title>selectores</title><style id=s></style>
|
|
<div id=r></div><script>
|
|
function lcg(x){return function(){x=(x*1103515245+12345)&0x7fffffff;return x/0x7fffffff}}
|
|
var r=lcg(41);
|
|
// Resolución de estilo: DOM profundo contra CIENTOS de reglas, muchas de las cuales NO casan.
|
|
// Es trabajo puro del motor de selectores, invisible para un benchmark de JS.
|
|
var reglas=[];
|
|
for(var i=0;i<600;i++){
|
|
var d=1+((r()*4)|0), sel=[];
|
|
for(var j=0;j<d;j++){
|
|
var t=r();
|
|
sel.push(t<0.3?(".c"+((r()*40)|0)) : t<0.55?("#n"+((r()*300)|0)) :
|
|
t<0.7?("div.c"+((r()*40)|0)+":nth-child("+(1+((r()*5)|0))+")") :
|
|
t<0.85?("[data-k='"+((r()*20)|0)+"']") : "div");
|
|
}
|
|
reglas.push(sel.join(r()<0.5?" ":" > ")+"{color:#"+(((r()*0xfff)|0)|0x400).toString(16)+"}");
|
|
}
|
|
document.getElementById('s').textContent=reglas.join("\n");
|
|
function arbol(p,prof){
|
|
if(prof===0) return "";
|
|
var n=2+((r()*3)|0),h="";
|
|
for(var i=0;i<n;i++)
|
|
// Con texto en las hojas, no sólo divs vacíos: si el árbol no pinta nada, la página entrena
|
|
// la resolución de estilo pero deja fuera el layout inline, que va en el mismo viaje.
|
|
var dentro = arbol(p+1,prof-1) || ("nodo "+((r()*1e6)|0).toString(36));
|
|
h+="<div id=n"+((r()*300)|0)+" class='c"+((r()*40)|0)+" c"+((r()*40)|0)+
|
|
"' data-k='"+((r()*20)|0)+"'>"+dentro+"</div>";
|
|
return h;
|
|
}
|
|
document.getElementById('r').innerHTML=arbol(0,7);
|
|
// Invalidar el estilo a propósito y forzar recálculo: el camino caliente de verdad.
|
|
var t=0, raiz=document.getElementById('r');
|
|
for(var i=0;i<40;i++){ raiz.className="v"+(i%5); t+=raiz.getBoundingClientRect().height; }
|
|
document.title="sel-"+(t|0);
|
|
</script>
|