Ah ok, that is clear about the devtools. Maybe there is a way to enhance
things for the memory snapshot too, I'm less certain about that and don't
see anything offhand.

Don't worry I'm definitely not going to rush into making any changes, and
I'm not worried specifically about making XML final - I won't do that. I
was only generally concerned with making sure it works by default as much
as possible with legacy code.



On Wed, Dec 11, 2019 at 12:24 PM Harbs <[email protected]> wrote:

> No. I just missed your email.
>
> I didn’t get your screenshot, but my point about developer tools was more
> with the profiling tools (i.e. heap memory references).
>
> As far as the memory improvements, I’ll have to do some more memory
> testing.
>
> Please don’t make XML a final class. One of my optimizations in my app was
> to subclass XML and make a phony XML node which just keeps a string version
> for subsequent XML writes. Having XML as final would make that very
> difficult.
>
> > On Dec 11, 2019, at 1:06 AM, Greg Dove <[email protected]> wrote:
> >
> > I replied to a 'commits@' email a couple of days back. Maybe that goes
> nowhere?
> >
> > Copying and pasting here:
> >
> >
> > 1. In Chrome tools, goto settings (via three vertical dots in top right)
> and make sure 'Enable custom formatters' is checked under Console settings.
> >
> > 2. back in the console, copy and paste the following code:
> > var xmlStyles = {
> > 'element': {'style':'color:blue'},
> > 'text': {'style':'color:green'},
> > 'processing-instruction': {'style':'color:orange'},
> > 'comment': {'style':'color:grey'},
> > 'attribute' : {'style':'color:purple'},
> > 'default': {'style':'color:black'}
> > }
> >
> > function getLevelIndentation(level){
> >     return level * 10 + "px";
> > }
> >
> > window.devtoolsFormatters = [{
> >     header: function(obj, config){
> > if ((config && config.xmlFormat) || (XML && obj instanceof XML)) {
> > var kind = config? config.kind: obj.nodeKind();
> > var atts = xmlStyles[kind] || xmlStyles['default'];
> > var name;
> > if (kind == 'element') {
> > var childCount = obj.getChildrenArray().length;
> > if (childCount) {
> > name = '<'+obj.name <http://obj.name/>().toString()+
> '>('+childCount+')';
> > } else {
> > name = '<'+obj.name <http://obj.name/>().toString()+ '/>';
> > }
> > } else {
> > name = '('+ kind+')';
> > }
> > var display = 'XML '+name;;
> > var isAttribute = (kind == 'attribute')
> > if (isAttribute) display += ' '+obj.name <http://obj.name/
> >().toString()+'="'+obj.getValue()+'"';
> >
> > return ["div", atts, display]
> > }
> >      return null;
> >     },
> > hasBody: function(){
> >         return true;
> >     },
> > body: function(obj, config){
> > var level = config !== undefined ? config.level : 1;
> > switch(obj.nodeKind()) {
> > case 'element':
> > var children = obj.getChildrenArray();
> > children = children.map(function(child){
> > var kind = child.nodeKind();
> > var atts = xmlStyles[kind];
> > child = ["object", {
> > object: child,
> > config: {
> > kind: kind,
> > xmlFormat: true,
> > level: level + 1
> > }
> > }];
> > return ["div", {style: "margin-left: " + getLevelIndentation(level)},
> child]
> > })
> > var atts = obj.getAttributeArray();
> > if (atts.length) {
> > atts = atts.map(
> > function(att){
> >
> > return ["div", {style: xmlStyles['attribute'].style+";margin-left: " +
> getLevelIndentation(level)}, 'XML (attribute) ' + att.name <
> http://att.name/>().toString()+'="'+att.getValue()+'"']
> > }
> > )
> > children = atts.concat(children);
> > }
> > break;
> > case 'processing-instruction':
> > case 'comment':
> > return ["div", {style: "margin-left: " + getLevelIndentation(level)},
> obj.toXMLString()];
> > break;
> >
> > default:
> >
> > return ["div", {style: "margin-left: " + getLevelIndentation(level)},
> obj.getValue()];
> > break;
> >
> > }
> > return ["div", {}].concat(children);
> >
> >     }
> >
> > }]
> >
> >
> > 3. Try the following:
> > XML.ignoreComments=false
> > XML.ignoreProcessingInstructions=false
> > var xml = new XML('<test><?processingInstruction ?><!--and a
> comment-->something<child withAttribute="childAttributeValue">child
> text</child></test>');
> >
> > xml (and press enter)
> >
> > You should be able to inspect the xml in a custom way:
> >
> >
> >
> >
> >
> > On Wed, Dec 11, 2019 at 12:00 PM Harbs <[email protected] <mailto:
> [email protected]>> wrote:
> > I’m not sure what enhancement you’re referring to.
> >
> > If you can get similar memory requirements some other way, I don’t mind
> reverting what I did.
> >
> > I made so many small tweaks, that I’m not totally sure exactly what made
> the differences (besides the obvious).
> >
> > It might be worth comparing back to your string references to see the
> differences.
> >
> > > On Dec 11, 2019, at 12:45 AM, Greg Dove <[email protected] <mailto:
> [email protected]>> wrote:
> > >
> > > 'I don’t think subclassing effects language conformity. Am I wrong?'
> > >
> > > I guess it depends what each of us thinks of as 'language'. Because
> XML is
> > > an as3 core type, I think of it as part of language. Another way to
> think
> > > of it is whether or not it would work the same in AVMPlus (which is
> > > 'bare-bones' as3 types, and which  I use for testing sometimes
> locally).
> > > The change can certainly break certain patterns that may have been
> used.
> > > One of them I can think of is not that unusual, such as:
> > > switch(obj.constructor) {
> > > case XML:
> > >
> > > break;
> > > case SomethingElse:
> > >
> > > break;
> > >
> > > }
> > > The above would potentially no longer work the same.
> > >
> > > It's more the case that if something can work the same, I feel like it
> > > should, to keep things as consistent and reliable as possible. That
> > > certainly is what clients are telling me they are looking for when
> porting
> > > a legacy app, and it is one of the biggest credibility challenges that
> > > Royale has to address in terms of gaining acceptance with a new user :
> > > 'Does it really work the same?'
> > > We often say that for porting to Royale, the business logic should
> remain
> > > the same and the majority of the work is in the views. I don't know how
> > > many you've worked on, but I've worked on 4 large codebases now. If I
> > > reflect on the past year, the majority of my effort and biggest issues
> were
> > > actually with problems related to business logic, probably AMF related
> with
> > > Carlos and XML for another recent client. The view stuff has been
> > > relatively easy (there absolutely are things to improve in this area
> still,
> > > but the problems have been 'minor' by comparison). So please forgive
> me if
> > > I tend to be a little resistant to anything that might make business
> logic
> > > stuff work less often than it otherwise could, I am only focusing on
> what I
> > > think is best for Royale.
> > >
> > > Where subclassing helps is that the browser tools group instances by
> class,
> > > so this way, you get (most of) elements, text and attributes grouped
> > > separately
> > >
> > > Did you try the dev tools enhancement that I posted elsewhere? I'm
> pretty
> > > sure that objective can be achieved without any changes to the Royale
> > > classes, and you can even have color coding for the different XML
> nodeKinds
> > > etc. I think we could probably do that support for any
> _ROYALE_CLASS_INFO
> > > instance providing custom inspection or even separation of private
> members
> > > from public etc to avoid visual clutter in the browser tools. At least
> I
> > > know it can be done in Chrome. I think it might be supported in some
> other
> > > browsers, but did not try that yet. We could probably make
> debugging/dev
> > > support a whole lot nicer in general with external stuff like this.
> > >
> > >
> > > On Wed, Dec 11, 2019 at 11:17 AM Harbs <[email protected] <mailto:
> [email protected]>> wrote:
> > >
> > >> The subclass approach prevents the need to keep a record of the node
> type
> > >> for the vast majority on nodes.
> > >>
> > >> I no longer have clear data on how much that helped for memory, but I
> > >> think it helped somewhat.
> > >>
> > >> Feel free to do more investigation into that.
> > >>
> > >> I don’t think subclassing effects language conformity. Am I wrong?
> Where
> > >> subclassing helps is that the browser tools group instances by class,
> so
> > >> this way, you get (most of) elements, text and attributes grouped
> > >> separately.
> > >>
> > >> Thanks,
> > >> Harbs
> > >>
> > >>> On Dec 10, 2019, at 11:56 PM, Greg Dove <[email protected]
> <mailto:[email protected]>> wrote:
> > >>>
> > >>> That does sound like a great improvement, Harbs. Congrats on the
> massive
> > >>> memory improvements!
> > >>>
> > >>> If the 'subclass' approach for attributes and text was not the main
> basis
> > >>> for achieving the improvements, do you consider that we can avoid
> those
> > >>> subclasses and restore the more conforming actionscript 3
> implementation?
> > >>>
> > >>> If that change with subclasses was for ease of debugging only, then
> I'd
> > >> be
> > >>> keen to find better ways to make debugging easier as I mentioned
> > >> elsewhere,
> > >>> keeping language conformance for what is a core as3 type, and
> therefore
> > >>> keeping the best chance of what we have working with all legacy code.
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> On Wed, Dec 11, 2019 at 1:55 AM Harbs <[email protected]
> <mailto:[email protected]>> wrote:
> > >>>
> > >>>> One thing to keep in mind with XML:
> > >>>>
> > >>>> If you keep even a single node (element or attribute) in memory,
> that
> > >> will
> > >>>> retain your entire tree.
> > >>>>
> > >>>> Make sure you use copy() (or setParent(null)) to get rid of parent
> > >>>> references for leaf nodes that might be kept.
> > >>>>
> > >>>> HTH,
> > >>>> Harbs
> > >>>>
> > >>>>> On Dec 10, 2019, at 1:14 PM, Piotr Zarzycki <
> [email protected] <mailto:[email protected]>
> > >>>
> > >>>> wrote:
> > >>>>>
> > >>>>> Hi Harbs,
> > >>>>>
> > >>>>> Great work! We are using in our app XML - didn't check earlier
> memory
> > >>>>> consumption, but it looks like really good improvement.
> > >>>>>
> > >>>>> Thanks,
> > >>>>> Piotr
> > >>>>>
> > >>>>> wt., 10 gru 2019 o 11:04 Harbs <[email protected] <mailto:
> [email protected]>> napisał(a):
> > >>>>>
> > >>>>>> I just added code like this to the constructor:
> > >>>>>>
> > >>>>>> if(!_class_initialized)
> > >>>>>> {
> > >>>>>>      Object.defineProperty(XML.prototype,"0",
> > >>>>>>                      {
> > >>>>>>                              "get": function():XML{return this as
> > >>>> XML},
> > >>>>>>                              "set": function():void{},
> > >>>>>>                              enumerable: true,
> > >>>>>>                              configurable: true
> > >>>>>>                      }
> > >>>>>>      );
> > >>>>>>      _class_initialized = true;
> > >>>>>> }
> > >>>>>>
> > >>>>>> where _class_initialized is a static boolean.
> > >>>>>>
> > >>>>>> This sliced the memory requirements for XML instances in roughly
> half!
> > >>>>>>
> > >>>>>> Not totally thrilled with the conditional code in the constructor,
> > >> but I
> > >>>>>> don’t have any better ideas at the moment.
> > >>>>>>
> > >>>>>> Between the improvements I’ve made to XML and aggressive work on
> > >>>> removing
> > >>>>>> extraneous object references (particularly XML), I’ve reduced the
> > >> memory
> > >>>>>> footprint of my app for a particularly complex document from about
> > >> 155MB
> > >>>>>> down to 103MB.
> > >>>>>>
> > >>>>>> The memory impact of using XML went from about 75MB down to 22MB.
> > >>>> (That’s
> > >>>>>> for well over 100,000 nodes kept in memory.)
> > >>>>>>
> > >>>>>> Not bad for a few days work… ;-)
> > >>>>>>
> > >>>>>> Harbs
> > >>>>>>
> > >>>>>>> On Dec 9, 2019, at 7:19 PM, Greg Dove <[email protected]
> <mailto:[email protected]>> wrote:
> > >>>>>>>
> > >>>>>>> btw I am still happy to look into the possibility of doing a
> first
> > >> time
> > >>>>>>> 'get' access for the Class itself on its package that runs static
> > >> code,
> > >>>>>> but
> > >>>>>>> as Alex pointed out, it could have issues with the minified
> version,
> > >> so
> > >>>>>> it
> > >>>>>>> is more at 'investigate' rather than 'solution' stage. I have not
> > >>>>>>> prioritized this for now...
> > >>>>>>>
> > >>>>>>>
> > >>>>>>> On Tue, Dec 10, 2019 at 6:13 AM Greg Dove <[email protected]
> <mailto:[email protected]>>
> > >> wrote:
> > >>>>>>>
> > >>>>>>>> This might be a good candidate for getting the static
> initialization
> > >>>>>> code
> > >>>>>>>> block working (it is currently not in js).
> > >>>>>>>>
> > >>>>>>>> We discussed that recently in another thread.
> > >>>>>>>>
> > >>>>>>>> public class MyClass{
> > >>>>>>>>
> > >>>>>>>> {//static init block
> > >>>>>>>> COMPILE::JS{
> > >>>>>>>> Object.defineProperty(MyClass.prototype,"0",
> > >>>>>>>>     {
> > >>>>>>>>             "get": function(){return this},
> > >>>>>>>>             "set": function(){},
> > >>>>>>>>             enumerable: true,
> > >>>>>>>>             configurable: true
> > >>>>>>>>     }
> > >>>>>>>> );
> > >>>>>>>> }
> > >>>>>>>> }
> > >>>>>>>>
> > >>>>>>>> public function  MyClass (){
> > >>>>>>>>
> > >>>>>>>> }
> > >>>>>>>>
> > >>>>>>>> }
> > >>>>>>>>
> > >>>>>>>> On Tue, Dec 10, 2019 at 6:00 AM Alex Harui
> <[email protected]
> > >>>
> > >>>>>>>> wrote:
> > >>>>>>>>
> > >>>>>>>>> Did you try:
> > >>>>>>>>>
> > >>>>>>>>> function get 0():XML { return this; }
> > >>>>>>>>> function set 0(value:XML) {}
> > >>>>>>>>>
> > >>>>>>>>> Within a COMPILE::JS, I think the variables:
> > >>>>>>>>>
> > >>>>>>>>> this["constructor"]
> > >>>>>>>>> this["__proto__"]
> > >>>>>>>>>
> > >>>>>>>>> are available.
> > >>>>>>>>>
> > >>>>>>>>> HTH,
> > >>>>>>>>> -Alex
> > >>>>>>>>>
> > >>>>>>>>> On 12/9/19, 8:27 AM, "Harbs" <[email protected] <mailto:
> [email protected]>> wrote:
> > >>>>>>>>>
> > >>>>>>>>> In my question to minimize memory requirements in XML, I’d
> like to
> > >>>>>>>>> optimize the zero index accessor.
> > >>>>>>>>>
> > >>>>>>>>> Right now, we have Object.defineProperty in the XML
> constructor.
> > >>>> The
> > >>>>>>>>> byproduct of that is we have a function defined on every single
> > >>>>>> instance of
> > >>>>>>>>> XML. Ideally that should be on the prototype object. This
> should
> > >>>>>>>>> drastically reduce the memory requirements for instantiating
> XML.
> > >>>>>>>>>
> > >>>>>>>>> In JS, that’s pretty easy to do:
> > >>>>>>>>>
> > >>>>>>>>> Object.defineProperty(thePrototype,"0",
> > >>>>>>>>>     {
> > >>>>>>>>>             "get": function(){return this},
> > >>>>>>>>>             "set": function(){},
> > >>>>>>>>>             enumerable: true,
> > >>>>>>>>>             configurable: true
> > >>>>>>>>>     }
> > >>>>>>>>> );
> > >>>>>>>>>
> > >>>>>>>>> I’m struggling with how to do it in AS3. How can we get a
> > >> reference
> > >>>>>>>>> to the prototype outside the constructor or have the compiler
> > >>>> construct
> > >>>>>>>>> this kind of function automatically?
> > >>>>>>>>>
> > >>>>>>>>> Thoughts?
> > >>>>>>>>> Harbs
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>
> > >>>>> --
> > >>>>>
> > >>>>> Piotr Zarzycki
> > >>>>>
> > >>>>> Patreon: *https://www.patreon.com/piotrzarzycki <
> https://www.patreon.com/piotrzarzycki>
> > >>>>> <https://www.patreon.com/piotrzarzycki <
> https://www.patreon.com/piotrzarzycki>>*
> > >>>>
> > >>>>
> > >>
> > >>
> >
>
>

Reply via email to