That sounds great for sure, Josh. I suspect the 4KB savings comparison might be before the release javascript is gzipped? I tend to use 7zip (on Windows) to gzip the release build javascript from the 2 variations and compare those, using gzip here to mirror what difference it would make in usual real world conditions. It can sometimes be a bit demoralizing when you see the smaller difference in absolute terms when comparing gzipped variants, but if you look at the percentage improvements it is probably still quite a good improvement.
fyi I just fixed an annotation directive that was not working correctly at the class level (it was at individual member level previously). If something is never needed for reflection and is only for static constants, like your example, then marking it as @royalesuppressexport at the class level might even do something with similar results in the release build - for that specific class only. But of course it is not a simple configuration setting for the whole build, like you are doing. On Fri, Aug 9, 2019 at 3:06 AM Josh Tynjala <[email protected]> wrote: > My goal is to be able to completely omit classes from release builds when > their only purpose is to define a bunch of constants. Usually, you only > need a small number of the constants, so the rest of them bloat your app > for no good reason. > > I made a test project with a class that defines 100 Number constants. When > combined this inline-constants option with a hacky tweak to the compiler > that omitted the constant definitions from the output, it made the release > build 4KB smaller. I still need to figure out how to do that in a non-hacky > way, but that kind of reduction is really promising. > > -- > Josh Tynjala > Bowler Hat LLC <https://bowlerhat.dev> > > > On Wed, Aug 7, 2019 at 2:47 PM Greg Dove <[email protected]> wrote: > > > Hey Josh, that sounds pretty cool. I'm not sure, but it might however be > > duplicating some aspects of what GCC already does when it optimizes > because > > I expect it might do the same types of thing when it processes the @const > > annotations in the debug code hints. > > Also, for example, strings are only included once in the js-release build > > if they are above a minimal length and then accessed by reference > > irrespective of what inlining changes were made in the debug code output. > > This ends up being similar conceptually to SWF's (and AMF) string tables > I > > think, although I did not check whether that changed since the ASC 2.0 > > inlining support. > > > > fyi I have a local compiler branch from FlexJS days where I have bindings > > for (static) primitive constants being converted to initialization value > > assignments with inline values instead of *actual bindings*, similar to > > what I assume you are doing here, but as a way to avoid running binding > > code for simple static constant bindings. I will revisit that at some > point > > soon, It might help improve startup speed for some people. > > > > > > > > On Thu, Aug 8, 2019 at 9:09 AM <[email protected]> wrote: > > > > > This is an automated email from the ASF dual-hosted git repository. > > > > > > joshtynjala pushed a commit to branch develop > > > in repository https://gitbox.apache.org/repos/asf/royale-compiler.git > > > > > > > > > The following commit(s) were added to refs/heads/develop by this push: > > > new 61479f5 compiler-jx: added inline-constants compiler option > for > > > JS builds to optionally inline the values of primitive constants (like > > > Number, String, Boolean, int, and uint) instead of referencing them. > > > 61479f5 is described below > > > > > > commit 61479f5cce3c4ea582a1a6a859f1e74ef9256a9f > > > Author: Josh Tynjala <[email protected]> > > > AuthorDate: Wed Aug 7 13:52:59 2019 -0700 > > > > > > compiler-jx: added inline-constants compiler option for JS builds > to > > > optionally inline the values of primitive constants (like Number, > String, > > > Boolean, int, and uint) instead of referencing them. > > > > > > Defaults to false. It may make sense to switch this to true in the > > > future, but it's not stable yet. > > > > > > Does not yet skip unnecessary goog.require() calls, even though the > > > classes may no longer be referenced. Figuring out how to do this should > > > reduce the size of release builds. > > > --- > > > .../internal/codegen/js/jx/IdentifierEmitter.java | 37 > > > +++++++++++++++++++++- > > > .../driver/js/goog/JSGoogConfiguration.java | 19 +++++++++++ > > > 2 files changed, 55 insertions(+), 1 deletion(-) > > > > > > diff --git > > > > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > > > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > > index 4d42069..f6363ea 100644 > > > --- > > > > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > > +++ > > > > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > > @@ -19,9 +19,12 @@ > > > > > > package org.apache.royale.compiler.internal.codegen.js.jx; > > > > > > +import org.apache.royale.abc.ABCConstants; > > > import org.apache.royale.abc.semantics.Namespace; > > > import org.apache.royale.compiler.codegen.ISubEmitter; > > > import org.apache.royale.compiler.codegen.js.IJSEmitter; > > > +import org.apache.royale.compiler.constants.IASLanguageConstants; > > > +import org.apache.royale.compiler.definitions.IConstantDefinition; > > > import org.apache.royale.compiler.definitions.IDefinition; > > > import org.apache.royale.compiler.definitions.IFunctionDefinition; > > > import > > > > > > org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification; > > > @@ -37,6 +40,7 @@ import > > > > org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens; > > > import > > > > > > org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens; > > > import > > org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils; > > > import org.apache.royale.compiler.internal.definitions.*; > > > +import org.apache.royale.compiler.internal.projects.RoyaleJSProject; > > > import org.apache.royale.compiler.internal.tree.as > > > .BinaryOperatorAssignmentNode; > > > import org.apache.royale.compiler.internal.tree.as > > > .BinaryOperatorDivisionAssignmentNode; > > > import org.apache.royale.compiler.internal.tree.as > > > .MemberAccessExpressionNode; > > > @@ -76,12 +80,43 @@ public class IdentifierEmitter extends JSSubEmitter > > > implements > > > && !identifierIsAccessorFunction; > > > boolean emitName = true; > > > JSRoyaleEmitter fjs = (JSRoyaleEmitter)getEmitter(); > > > + RoyaleJSProject project = > > > (RoyaleJSProject)getWalker().getProject(); > > > boolean isCustomNamespace = false; > > > boolean isStatic = nodeDef != null && nodeDef.isStatic(); > > > if (nodeDef instanceof FunctionDefinition && > > > fjs.isCustomNamespace((FunctionDefinition)nodeDef)) > > > - isCustomNamespace = true; > > > + isCustomNamespace = true; > > > > > > + if (isStatic > > > + && nodeDef instanceof IConstantDefinition > > > + && project != null && project.config != null > > > + && project.config.getInlineConstants()) > > > + { > > > + IConstantDefinition constDef = (IConstantDefinition) > > nodeDef; > > > + Object initialValue = > constDef.resolveInitialValue(project); > > > + if (initialValue != null) > > > + { > > > + startMapping(parentNode); > > > + if(initialValue instanceof String) > > > + { > > > + write("\"" + initialValue + "\""); > > > + } > > > + else if(initialValue == ABCConstants.UNDEFINED_VALUE) > > > + { > > > + write(IASLanguageConstants.UNDEFINED); > > > + } > > > + else if(initialValue == ABCConstants.NULL_VALUE) > > > + { > > > + write(IASLanguageConstants.NULL); > > > + } > > > + else > > > + { > > > + write(initialValue.toString()); > > > + } > > > + endMapping(parentNode); > > > + return; > > > + } > > > + } > > > if (isStatic) > > > { > > > String sname = nodeDef.getParent().getQualifiedName(); > > > diff --git > > > > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > > > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > > index 45af81c..d4e5328 100644 > > > --- > > > > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > > +++ > > > > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > > @@ -512,4 +512,23 @@ public class JSGoogConfiguration extends > > > JSConfiguration > > > return ret; > > > } > > > > > > + // > > > + // 'inline-constants' > > > + // > > > + > > > + private boolean inlineConstants = false; > > > + > > > + public boolean getInlineConstants() > > > + { > > > + return inlineConstants; > > > + } > > > + > > > + @Config > > > + @Mapping("inline-constants") > > > + public void setInlineConstants(ConfigurationValue cv, boolean > value) > > > + throws ConfigurationException > > > + { > > > + inlineConstants = value; > > > + } > > > + > > > } > > > > > > > > >
