I couldn’t figure out a good way to benchmark it, but this feels snappier, unless I’m experiencing placebo. Certainly, I wasn’t seeing any speedup in the listener operations (did a simple fibonacci) but I could do something like paste a lot of text into a field and the UI wouldn’t completely bog down. It was still responsive.
Another one is Wigglypaint marker didn’t skip for me. Normally with my laptop (old Thinkpad) Wigglypaint JS, the marker is not a fluid line. I’m pretty sure this isn’t placebo, but again, I couldn’t figure out a good benchmark other than “feeling” the snappiness.
patch to lil.js that turns operation look ups to be inverse hashmaps:
diff --git a/js/lil.js b/js/lil.js
old mode 100755
new mode 100644
index 5c89b4d..07163fa
--- a/js/lil.js
+++ b/js/lil.js
@@ -237,6 +237,7 @@ monad={
return r
},
}
+monadk=Object.fromEntries(Object.keys(monad).map((e,i)=>[e,i]))
dyad={
'+': vd((x,y)=>lmn(ln(x)+ln(y))),
'-': vd((x,y)=>lmn(ln(x)-ln(y))),
@@ -453,6 +454,7 @@ table_swap_rows=(tab,a,b)=>{
if(a==b||a<0||b<0||a>tab_rowcount(tab)-1||b>tab_rowcount(tab)-1)return tab
const pv=monad.range(lmn(tab_rowcount(tab)));pv.v[a]=lmn(b),pv.v[b]=lmn(a);return dyad.take(pv,tab)
}
+dyadk=Object.fromEntries(Object.keys(dyad).map((e,i)=>[e,i]))
triad={
'@orderby': (col,tab,order_dir)=>{
const rt=orderby(tab,dyad.take(lmn(count(tab)),lml(ll(col))).v,ln(order_dir))
@@ -477,8 +479,9 @@ triad={
return lin(x)?r:dyad[','](lt(x),r)
},
}
+triadk=Object.fromEntries(Object.keys(triad).map((e,i)=>[e,i]))
-findop=(n,prims)=>Object.keys(prims).indexOf(n), as_enum=x=>x.split(',').reduce((x,y,i)=>{x[y]=i;return x},{})
+findop=(n,prims)=>prims[n], as_enum=x=>x.split(',').reduce((x,y,i)=>{x[y]=i;return x},{})
let tnames=0;tempname=_=>lms(`@t${tnames++}`)
op=as_enum('JUMP,JUMPF,JUMPT,LIT,DUP,DROP,SWAP,OVER,BUND,OP1,OP2,OP3,GET,SET,LOC,LOCS,AMEND,TAIL,CALL,BIND,ITER,EACH,NEXT,COL,IPRE,IPOST,FIDX,FMAP')
oplens= [ 3 ,3 ,3 ,3 ,1 ,1 ,1 ,1 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,1 ,1 ,1 ,1 ,3 ,3 ,1 ,3 ,3 ,3 ,3 ]
@@ -492,9 +495,9 @@ blk_gets=(x,i )=>0xFFFF&(blk_getb(x,i)<<8|blk_getb(x,i+1))
blk_op =(x,o )=>{blk_addb(x,o);if(o==op.COL)blk_addb(x,op.SWAP)}
blk_opa =(x,o,i)=>{blk_addb(x,o),blk_adds(x,i);return blk_here(x)-2}
blk_imm =(x,o,k)=>{let i=x.locals.findIndex(x=>match(x,k));if(i==-1)i=x.locals.length,x.locals.push(k);blk_opa(x,o,i)}
-blk_op1 =(x,n)=>blk_opa(x,op.OP1,findop(n,monad))
-blk_op2 =(x,n)=>blk_opa(x,op.OP2,findop(n,dyad ))
-blk_op3 =(x,n)=>blk_opa(x,op.OP3,findop(n,triad))
+blk_op1 =(x,n)=>blk_opa(x,op.OP1,findop(n,monadk))
+blk_op2 =(x,n)=>blk_opa(x,op.OP2,findop(n,dyadk ))
+blk_op3 =(x,n)=>blk_opa(x,op.OP3,findop(n,triadk))
blk_lit =(x,v)=>blk_imm(x,op.LIT,v)
blk_set =(x,n)=>blk_imm(x,op.SET,n)
blk_loc =(x,n)=>blk_imm(x,op.LOC,n)
@@ -659,10 +662,10 @@ parse=text=>{
blk_op3(b,'@ins');return
}
if(matchsp('(')){if(matchsp(')')){blk_lit(b,lml([]));return}expr(b),expect(')');return}
- const s=peek().v;if(findop(s,monad)>=0&&({'symbol':1,'name':1})[peek().t]){
+ const s=peek().v;if(findop(s,monadk)!==undefined&&({'symbol':1,'name':1})[peek().t]){
next();if(matchsp('@')){
let depth=0,l=lmblk();while(matchsp('@'))depth++
- expr(b),blk_opa(l,op.FMAP,findop(s,monad))
+ expr(b),blk_opa(l,op.FMAP,findop(s,monadk))
while(depth-->0){const t=tempname(),m=lmblk();blk_loop(m,[ls(t)],_=>{blk_get(m,t),blk_cat(m,l)}),l=m}
blk_cat(b,l)
}else{expr(b),blk_op1(b,s)};return
@@ -678,7 +681,7 @@ parse=text=>{
blk_sets(l,fidx,blk_here(l))
while(depth-->0){const t=tempname(),m=lmblk();blk_loop(m,[ls(t)],_=>{blk_get(m,t),blk_cat(m,l)}),l=m}
blk_cat(b,l);return
- }const s=peek().v;if(findop(s,dyad)>=0&&({'symbol':1,'name':1})[peek().t]){next(),expr(b),blk_op2(b,s)}
+ }const s=peek().v;if(findop(s,dyadk)!==undefined&&({'symbol':1,'name':1})[peek().t]){next(),expr(b),blk_op2(b,s)}
}
const b=lmblk();if(hasnext())expr(b);while(hasnext())blk_op(b,op.DROP),expr(b)
if(blk_here(b)==0)blk_lit(b,NIL);return b