scijs / ndarray

📈 Multidimensional arrays for JavaScript
MIT License
1.21k stars 61 forks source link

Code generation #34

Open patgrasso opened 7 years ago

patgrasso commented 7 years ago

Some solutions have been proposed to reduce the string concatenation (#11, #12). I'd like to pitch another alternative: code generation from a dynamically generated AST using escodegen.

You could have something like this:

const Sum = (exprs) => exprs.reduce((prev, curr) => BinOp(prev, '+', curr));

const strideTimesX = (i) => BinOp(
    Member(parse('this.stride'), Literal(i), true),
    '*',
    'x' + i
);

const getFactory = (d, type) => FunctionDecl(
    className(d, type) + '_get', args,
    Return(
      Member(
        parse('this.data'),
        Sum( range(d).map(strideTimesX).concat(thisOffset) ),
        true))));

esprima or acorn can also be used to generate the AST for the static portions of the code:

// from view.pick
let vars = acorn.parse('var a = [], b = [], c = this.offset;').body[0].expression;

FunctionDecl('pick', range(n).map((i) => 'x' + i),
  [ vars,
  //...
    Return(BinOp('a', '+', 'b')) ] // <-- not accurate, just an example

This would allow for runtime generation of the classes and retention of efficiency, but in a more controlled and maintainable way. It also reads somewhat intuitively (I've been playing around with escodegen, the above are working examples).

Let me know what you think. You can see updates in my fork patgrasso/ndarray (check out the escodegen branch).

bcolloran commented 6 years ago

@patgrasso -- I don't see an escodegen branch in that repo. Did you ever this working? What did you learn from your experimentation?

rreusser commented 6 years ago

One consideration: ndarray is 6.4kb minified whereas escodegen is 97kb minified.

patgrasso commented 6 years ago

Unfortunately I foolishly did not push any of my experimental changes and had a disk error. To reduce the build size, astring can be used instead of escodegen, which is ~16kb minified and supposedly much faster. Runtime performance should be unaffected barring constructor compilation. Additionally, it might be possible to move most of the code generation into the build process rather than occurring at runtime. I'll do some investigation to that end if the additional 16kb would still be too costly.