Skip navigation
Currently Being Moderated

Need Advice on improving script processing and ensuring completion

Jan 7, 2011 6:51 AM

Hi,

 

I have a program in which I am running a number of for loops which are doing a number of different things.  I pull in data from an xml file and then step through that data to dynamically create arrays, populate the arrays, and create and modify movie clips.

 

The program I'm building is similar in scope to one I developed in Director many years ago, and in that environment we had to actually put breaks in using timers to ensure that the data would be processed and that the system wouldn't choke.

 

What I'm seeing with this flash version of the application is similar and I suspect the same.  Basically, when navigating from the frame where the scripts are processed to the frame where the movie clips are displayed, there are times when it works perfectly and times when things are out of whack.  I put in a 5 second delay (arbitrarily) to see if this would resolve the issue and on my system at least it does.  But I need some advice on coming up with a real solution.

 

Any inofrmation you can give me about processing particularly as it relates to for loops and dynamic creation of elements (whether arrays or MCs) as well as making sure that everything is done woudl be greatly appreciated.

 

Best regards,

 

 

Chris McLaughlin

 
Replies
  • kglad
    62,058 posts
    Jul 21, 2002
    Currently Being Moderated
    Jan 7, 2011 7:13 AM   in reply to Chris McLaughlin

    on each system running your swf the length if time required to execute your code should be pretty consistant.  test your swf on the slowest system you want to target and find that time.  then in your publish settings/flash set your script time out to equal or exceed that time.

     
    |
    Mark as:
  • kglad
    62,058 posts
    Jul 21, 2002
    Currently Being Moderated
    Jan 7, 2011 7:49 AM   in reply to Chris McLaughlin

    just run your swf with a clock (with a second hand) next to your computer to see how long it takes your code to execute.  or set the timeout to a low number and increase it until you no longer see the script time-out warning.

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 7, 2011 5:57 PM   in reply to Chris McLaughlin

    First thing to remember when dealing with Flash is that its architecture is based on frames.Flash is constantly moving from one to another even when there is only one frame. In the applications that are not relying on frames per se frame progression is used to refresh screen. Frame is not a "physical" entity but an interval between screen refreshes. In other words moving to the next frame is a scheduled screen refresh which DOES NOT take precedence over code.

     

    This means that

     

    1. scripts are executed on frame-by-frame basis

    2. Flash WILL not move to another frame until ALL code on the current frame is executed.

     

    For example, if the next frame is scheduled to in 100 ms but the code execution in the current frame takes 200ms - Flash will move to another frame ONLY in 200ms. This is why set frame rate is usually not the actual frame rate and is slower.

     

    This is a bad news for applications that have bulky code and rely on frame rate animations. Especially this is true for timeline based animations.

     

    In addition, default script execution timeout is 15 seconds that can be increased.

     

    From performance optimization standpoint, I have a hard time to imagine an application that involves so much code in one frame that it chokes (even when thousands of objects are involved or thousands of loop iterations are performed). Perhaps, it can happen but, again, well thought out architecture will not allow for this kind of stuff to happen, especially because with AS3 event model one can easily pace out code execution.

     

    Message was edited by: Andrei1

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 7, 2011 7:57 PM   in reply to Chris McLaughlin

    You code is highly unreadable. I am sorry but I cannot go through over 500 lines and format them so it can be comprehended.

     

    I suggest you format the code properly including indents for each logical segment and post it as formatted using syntax highlight (arrow next to the smiley).

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 7, 2011 8:00 PM   in reply to Chris McLaughlin

    In addition, there are some strange closing curly brackets that make no sense and created a notion of nested functions.

     

    HTML spacer do not help either.

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 7, 2011 8:54 PM   in reply to Chris McLaughlin

    I looked at a part of your code and even a brief encounter uncovered huge number if inefficiencies. There are tons of redundancies, inefficient object referencing, unnecessary casting, undefined variables, etc.

     

    Timer that you implemented has no sense and I believe introduces significant performance hits.

     

    You are better off to start from scratch and post it here function by function in a logical manner that reflects the flow of your application.

     
    |
    Mark as:
  • kglad
    62,058 posts
    Jul 21, 2002
    Currently Being Moderated
    Jan 7, 2011 10:12 PM   in reply to Chris McLaughlin

    you're welcome.


     
    |
    Mark as:
  • Currently Being Moderated
    Jan 8, 2011 9:53 AM   in reply to Chris McLaughlin

    "and starting over is simply not an option at this point."

     

    I am sorry you feel this way because without revamping the code you have shown you will not attain decent performance.

     

    Besides the code it feels like XML structure is not efficient as well - this is an impressions I got from how you parse XML. For the future references data structure is EXTREMELY important for application performance optimization.

     

    In case you decide to rethink the architecture here is an example how you can improve your code. Note, I did not test the code - it is just a concept. In addition, this is just a partial improvement. You parsing routine should be rewritten altogether.

     

    This code addresses the following inefficiencies:

     

    You parse through the same entity at least two times when you can do it in a single loop. In this example you parse through ICPcontent.product[0] in buildAssurity()  and then in buildAssuritySlides(). The drawback is that you introduce an extra loop and have to declare extra variables.On the other hand you reference the same entity numerous times through making Flash searching for them every time. For instance:

     

    scrollPane1_mc["sub" + (a + 1) + "_mc"].text = segmentTitle;
    scrollPane1_mc["sub" + (a + 1) + "_mc"].autoSize = TextFieldAutoSize.CENTER;
    scrollPane1_mc["sub" + (a + 1) + "_mc"].selectable = false;
    textHeight = scrollPane1_mc["sub" + (a + 1) + "_mc"].height;
    

     

    Is much less efficient and much more cumbersome than:

     

    var tf:TextField = scrollPane1_mc["sub" + (a + 1) + "_mc"].sbText_tf;
    tf.text = segmentTitle;
    tf.autoSize = TextFieldAutoSize.CENTER;
    tf.selectable = false;
    textHeight = tf.height;
    

     

    Code below combines buildAssurity()  and buildAssuritySlides() into a single processing unit. In this example extra conditional logic is removed and more streamlined references are introduced. Read comments:

     

    function buildAssurity():void {
         // keep reference for reusing
         var xmlList:XMLList = ICPcontent.product[0];
         // define reference so that Flash doesn't have to make an effort to read length of node
         var len:int = xmlList.length();
         // the same as len
         var slideLen:int;
         // create a single reference to text field so that you can reuse it
         var tf:TextField;
         // iterators
         var s:int = 0;
         for (var i:int = 0; i < len; i++) {
              // you declare it in a higher scope, so for noe it is OK
              segmentTitle = xmlList.segmentName[i].text();
              // create array so that you can reference it
              var segArray:Array = [];
              slideLen = xmlList.segmentSlides[i].slide.length();
              for (s = 0; s < slideLen; s++) {
                   segSlide = xmlList.segmentSlides[i].slide[s].text();
                   segArray.push(segSlide)
              }
              // assign Array value to whatever
              // by the way, why is MovieClip designed to hold array?
              tl["Assurity_" + segmentTitle + "_Array"] = segArray;
              // THIS PART MAKES NO SENSE BECAUSE ARRAY HAS NO NAME PROPERTY
              tl["Assurity_" + segmentTitle + "_Array"].name = "Assurity_" + segmentTitle + "_Array";
              // deal with text field
              tf = scrollPane1_mc["sub" + (i + 1) + "_mc"].sbText_tf;
              tf.text = segmentTitle;
              tf.autoSize = TextFieldAutoSize.CENTER;
              tf.selectable = false;
              textHeight = tf.height;
              // this is exactly what it was without unneeded extra conditionals
              if(textHeight < 35) {
                   tf.y = 26;
              } 
              else if ((textHeight > 22) && (textHeight < 50)) {
                   tf.y = 17;
              }
              else {
                   tf.y = 10;
              }
         }
    }
    

     

    The same can be done with buildComfortis() and buildComfortisSlides() as well as buildReconcile() and buildComfortisSlides().

     

    As a matter of fact these three redundancies (six methods) are so similar that they can (and should) be combined into a single method which will reduce code and processing time in half.

     

    " I'm afraid I'm still a novice when it comes to formatting it for proper display on this forum."

     

    Sorry but it takes only a couple of clicks (arrow next to smiley >> your highlight choice).

     

    In addition, you owe it to yourself to make code readable, right?

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 8, 2011 10:44 AM   in reply to Chris McLaughlin

    Yes, I thought about it more and even with all the inefficiencies of the presented code it looks like the bottleneck is elsewhere. What frame 1 code does it is just XML parsing which is a fast process event with huge XMLs.

     

    I suspect that you need to look into something that happens after XML is parsed. What happens? Do you load images? How many?

     

    Also, it looks like you have a lot of hardcoded objects on timeline or in other clips on timeline. Is it true?

     

    In addition, it seems that objects in teh application are linked to XML values. In other words there are as many objects as values in XML. Is this assumption also true?

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 9, 2011 1:11 PM   in reply to Chris McLaughlin

    If the problems you have are related to the project you describe in the thread, it doesn't matter if it is AIR or is targeted for the web. AS3 is AS3 is AS3 anywhere. I feel your application has design problems and, of course, I cannot be more specific because I did not see is.

     

    Also, frankly, I am not a fan of timeline coding and avoid it like plague precisely for the code manageability/performance issues. So, I am not sure I will be willing to help beyond specific code pieces and architecture advise.

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 10, 2011 4:24 PM   in reply to Chris McLaughlin

    Chris,

     

    You did not go into details of your entire application but it feels like it is just a slide show (or, at least, a part of it is a slide show). Slide shows are done millions of times and, it appears, is the first application the majority of Flash developers start with. I am saying it because it is a pretty simple application and even with hundreds of images it performs well.It shouldn't be more than 50KB (without external images, of course).

     

    I am writing this to encourage you to revamp the thing. It may feel terrifying but the truth is that in 90% of cases difficulties grow like a snowball because architecture was never thought out and what people often do is just jumping into coding. There is no a good remedy for a sub-par design. Code re-factoring and bottleneck chasing takes 100 times longer than coding from scratch.

     

    Believe it or not, writing of a good, well architected applications is just 15% of an effort and takes very little time as a matter of fact. Good programming is not as much about knowledge of libraries as about an ability to come up with top level language-independent concepts.

     

    AS3, even if it is done on timeline, offers great ways to write OO applications with reusable code and objects. This is, in many ways, a key to good software performance.

     

    So, what do you say?

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 10, 2011 4:43 PM   in reply to Chris McLaughlin

    One more thing.

     

    Actually your code is pretty cool conceptually. You are attempting to split functionality into smaller pieces to decrease the load on application per unit of time. There are whole frameworks written around this concept.

     

    Nevertheless, again, it just feels like an overkill in this particular case mainly because there are more streamlined ways to deal with payload in AS3. Especially as far as Timer is concerned (Timer is quite an unreliable thing despite the first notion that is one is in control of time). In particular, AS3 events model offers a huge advantage.

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 20, 2011 5:35 AM   in reply to Chris McLaughlin

    How does it work?

     

    Here are some little improvements. I commented them:

     

    function loadContent(e:Event):void {
         trace("load content triggered");
         productsArray = new Array();
         tempArray = new Array();
         AssuritySegmentsArray = new Array();
         ComfortisSegmentsArray = new Array();
         ReconcileSegmentsArray = new Array();
         // this is set to true by default
         //XML.ignoreWhitespace = true; 
         ICPcontent = new XML(e.target.data);
         productCount = ICPcontent.product.length();
         // declare iterators and length before loop
         var segLen:int;
         var sldLen:int;
         var tf:TextField;
         var products:XML;
         trace("the product count = " + productCount);
         for (prd = 0; prd < productCount; prd++) {
              //Assign XML Child to XML Object -- Not XMLList
              products = ICPcontent.product[prd];
              trace("product name = " + ICPcontent.product[prd].productName.text());
              trace("product name retrived from products XML = " + products.productName.text())
              productName = products.productName.text()
              trace("prd = " + prd + " productName = " + productName);
              productsArray.push(productName);
              segLen = products.segmentName.length();
              for( seg = 0; seg < segLen; seg++) {
                   segmentTitle = products.segmentName[seg].text();
                   // I understand prd = subNum
                   tf = scrollPane1_mc["sub" + prd + "_mc"].sbText_tf
                   tf.text = segmentTitle;
                   tf.autoSize = TextFieldAutoSize.CENTER
                   textHeight = tf.height
                   tf.selectable = false;
                   if(textHeight < 35) {
                        tf.y = 26;
                   } else if((textHeight > 22) && (textHeight < 50)) {
                        tf.y = 17;
                   } else {
                        tf.y = 10;
                   }
                   //Push the segment titles into Arrays;
                   //create arrays to hold segment slides;
                   //add slides to arrays   
                   sldLen = products.segmentSlides[seg].slide.length();
                   //tl is a variable that refeers to the top level
                   // the equivalent of using this[productName + "SegmentsArray"]
                   //allows reference to and dynamic creation of Arrays that can
                   //be accessed 
                   tl[productName + "SegmentsArray"].push(segmentTitle);
                   tl[productName + "_" + segmentTitle + "_Array"] = new Array();
                   for (sld = 0; sld < sldLen; sld++) {
                        tl[productName + "_" + segmentTitle + "_Array"].push(String(products.segmentSlides[seg].slide[sld].text()))
                   }
              }     
              // prd = subNum?
              //subNum++ 
         }
     
    }
     
     
    
     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points