Optimization Tips

Re: Optimization Tips

Postby glro » Sun Aug 19, 2012 2:09 pm

Dan Rathbun wrote:
Dan Rathbun wrote:its nice but...
The code needs updating. It needs to search by ID instead.
(Or have arrays of the Inspector captions in all the local versions.)

Ooops.. just checked. The Outliner does not have an ID.
But Jim's system call 'may' work. The window object can have a different "name" than the text displayed on the caption bar.
Someone running a non-English version could test it and let us know.


I run a spanish computer using french as default language, and it doesn't work...

But there is a simple way to do it, using the standard line of code you mentioned, plus a messagebox

Code: Select all
result = UI.messagebox "if the outliner window is opened, close it?'", MB_YESNO
  if result == 6 #yes
     #close or open the outliner window
      status=UI.show_inspector "Outliner"
      if status==false then
        UI.show_inspector "Outliner"
      end
 end


This way, you don't toggle on the outliner window if it is not opened already, and if it is, you close it
0

glro 
 

Re: Optimization Tips

Postby Dan Rathbun » Sun Aug 19, 2012 3:30 pm

Actually we cannot close inspectors singly. Once they are open, we can only collapse or expand them.
0
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: Optimization Tips

    Postby TIG » Sun Aug 19, 2012 3:44 pm

    For Windows windows only - using Win32API.so - which you'll need to 'require'...
    You can 'close' just one window thus:
    closeWindow("Outliner")
    where:
    Code: Select all
    def closeWindow(name)
        findWindow = Win32API.new("user32.dll","FindWindow",['P','P'],'N')
        pw=findWindow.call(0,name)
        sendMessage = Win32API.new("user32.dll","SendMessage",['N','N','N','P'],'N')
        sendMessage.call(pw,0x0112,0xF060,0)#CLOSES
    end
    You can check if a window is 'visible' with:
    Code: Select all
    def windowIsVisible?(name)
        findWindow = Win32API.new("user32.dll","FindWindow",['P','P'],'N')
        isWindowVisible= Win32API.new("user32.dll","IsWindowVisible",['P'],'N')
        pw=findWindow.call(0,name)
        return isWindowVisible.call(pw)==1
    end
    Incidentally, the roll 'up'/'down' methods I often use are:
    Code: Select all
    def toggleRollUp(name)
        findWindow = Win32API.new("user32.dll","FindWindow",['P','P'],'N')
        pw=findWindow.call(0,name)
        sendMessage = Win32API.new("user32.dll","SendMessage",['N','N','N','P'],'N')
        sendMessage.call(pw,0x00a1,2,"")#WM_NCLBUTTONDOWN
        sendMessage.call(pw,0x0202,0,"")#WM_LBUTTONUP
    end
    def isRolledUp?(name)
        findWindow = Win32API.new("user32.dll","FindWindow",['P','P'],'N')
        getWindowRect= Win32API.new("user32.dll","GetWindowRect",['P','PP'],'N')
        pw=findWindow.call(0,name)
        data=Array.new.fill(0.chr,0..4*4).join
        getWindowRect.call(pw,data)
        rect=data.unpack("i*")
        #if window height is less than 90 then the window is rolledup
        return (rect[3]-rect[1]) < 90
    end
    ... using isRolledUp?("Outliner") to then toggleRollUp("Outliner") to roll it up if it's down etc...
    0
    TIG
    User avatar
    TIG 
    Global Moderator
     

    Re: Optimization Tips

    Postby glro » Mon Aug 20, 2012 8:50 am

    Dan Rathbun wrote:Actually we cannot close inspectors singly. Once they are open, we can only collapse or expand them.


    i am surely missing something

    you are right; the window is not closed, only collapsed

    but it is sufficient; my experience is that sketchup doesn't crash anymore
    0

    glro 
     

    Re: Optimization Tips

    Postby TIG » Mon Aug 20, 2012 9:20 am

    Collapsing [rolling-up] the Outliner is sufficient to stop it updating and causing bugsplats.
    However, my methods just posted do also 'close' the window if desired - but this might be annoying for users [?]... remember to use the 'locale' name for the window...
    0
    TIG
    User avatar
    TIG 
    Global Moderator
     

    Re: Optimization Tips

    Postby thomthom » Fri Oct 12, 2012 12:11 pm

    Page 152
    http://www.slideshare.net/tenderlove/zo ... de-so-slow

    attr_accessor :property vs def property; @property; end

    attr_accessor wins.

    Video of the presentation where the linked slideshow was used: http://confreaks.com/videos/427-rubycon ... de-so-slow
    0
    Thomas Thomassen — SketchUp Monkey & Coding addict
    List of my plugins and link to the CookieWare fund
    User avatar
    thomthom 
    PluginStore Author
    PluginStore Author
     

    Re: Optimization Tips

    Postby Dan Rathbun » Fri Oct 12, 2012 7:18 pm

    That would be in the sub-catagory of load optimization.

    However, later is there any difference when instances are instantiated ??

    :?:
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: Optimization Tips

      Postby thomthom » Fri Oct 12, 2012 10:05 pm

      What do you mean?
      0
      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund
      User avatar
      thomthom 
      PluginStore Author
      PluginStore Author
       

      Re: Optimization Tips

      Postby Dan Rathbun » Sat Oct 13, 2012 2:12 am

      The attr_* creation call is run on the C side so is bound to be faster. There is no parsing of text characters that make up the method definition, and translating to C-calls.

      Also the built-in creates the @var and sets it to nil, so the pure Ruby version would also need to do that (within the initialize method, just to be fair.)


      This work is all defintion work, done when the class is parsed and defined. It is only done once.

      Who's classes have a million accessor methods that need to be defined ?

      What I mean?
      .. is that later, at Runtime, when actually calling the accessor method, to get the value of the instance variable, is there a speed difference between the method created by the C-call, and the method created by the Pure Ruby definition ?

      I read the example as measuring the difference in method instance creation times. (Even methods are instances of a class object.)
      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: Optimization Tips

        Postby thomthom » Sat Oct 13, 2012 9:48 am

        Have a look at the slideshow linked - from page 152 - it displays what does on on the C side and explains the difference. It also shows graphs for the speed difference.

        The whole presentation is also interesting.
        0
        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund
        User avatar
        thomthom 
        PluginStore Author
        PluginStore Author
         

        Re: Optimization Tips

        Postby Dan Rathbun » Sat Oct 13, 2012 4:07 pm

        I did.. It is not clear.
        0
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          Re: Optimization Tips

          Postby thomthom » Tue Oct 23, 2012 11:30 am

          Dan Rathbun wrote:I did.. It is not clear.

          Page 154 vs 155 - you can see it does quite a lot of different things. On 154 which is the code for attr_reader it just directly fetches the value. In page 155 you can see it invokes a whole lot more (explained partly on page 156).
          0
          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund
          User avatar
          thomthom 
          PluginStore Author
          PluginStore Author
           

          Re: Optimization Tips

          Postby jolran » Tue Mar 12, 2013 1:24 pm

          if vector1.samedirection?(vector2) => do something.... end

          seams a little faster than:

          next unless vector1.samedirection?(vector2) => do something...



          Havent done any vigourious testing, could be specific case for me or maybe just a difference between if and unless.

          Just wanted to mention I noticed some difference in speed for the 2 cases.
          0
          User avatar
          jolran 
          PluginStore Author
          PluginStore Author
           

          Re: Optimization Tips

          Postby thomthom » Tue Mar 12, 2013 2:32 pm

          Got some numbers? I'd be surprised if there was a change due to if vs unless.

          Isn't it the "do something" that makes the difference here? Because you're comparing inverted logic that control whether "do something" is executed or not...
          0
          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund
          User avatar
          thomthom 
          PluginStore Author
          PluginStore Author
           

          Re: Optimization Tips

          Postby jolran » Tue Mar 12, 2013 4:30 pm

          We are talking ms here, but still a consistent difference for me.

          I was doing the condition inside a for loop.

          Isn't it the "do something" that makes the difference here? Because you're comparing inverted logic that control whether "do something" is executed or not...


          Maybe, I don't quite know the difference :oops:

          This was at the end of the loop, so the loop would restart again anyway if the "if" statement was false and there where more items to process.
          My theory was to shortcut whats inside the if statement and just go ahead to the next one. But that was slower..

          I have also noticed the same kind of ms speedgain when using if @edge VS if @edge == true while setting
          true or false elsewhere in the script.
          But that is probably more logic, although one could possibly expect that only if @edge needs to do more lookups.

          Again I could be overlooking something fundamental gotcha in Ruby, needs testing by others.
          Maybe next time I'll test I 'll get opposite results :)

          Edit: It could have something to do with that the if statement has an end in this case?
          So the code get's encapsulated or something.
          next unless vector1.samedirection?(vector2) => do something... end. Doesent work.

          Anyway it shaved 2 seconds of a process that took 30 seconds.
          0
          User avatar
          jolran 
          PluginStore Author
          PluginStore Author
           

          Re: Optimization Tips

          Postby dkendig » Thu Oct 24, 2013 6:50 pm

          woof... just switched from using Entities.add_face to Entities.fill_from_mesh... sped up adding 100k faces significantly... Used to take over an hour, now it takes 3 minutes... ::blinks:: wow!

          ---- adding each face manually ----

          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 45.3479998111725 sec (10k model)
          inner_group.entities after import: 36232
          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: ... I had to stop after waiting 35 minutes... (100k model)
          inner_group.entities after import: 361832

          ---- using add poly ----

          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 2.85800004005432 sec (10k model)
          inner_group.entities after import: 37348
          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 209.193000078201 sec (100k model)
          inner_group.entities after import: 361832

          ---- using add point and add poly ----

          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 2.79900002479553 sec (10k model)
          inner_group.entities after import: 37348
          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 200.332000017166 sec (100k model)
          inner_group.entities after import: 361832

          ---- using add point and add poly, passing vert and face count ----

          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 3.19099998474121 sec (10k model)
          inner_group.entities after import: 37348
          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 182.280999898911 sec (100k model)
          inner_group.entities after import: 361832

          ---- using add point and add poly, passing vert and face count, passing arrays of floats instead of Point3d ----

          inner_group.entities prior to import: 0
          VfSTimer - addPreviewMeshToEntitiesObject: 179.599999904633 sec (100k model)
          inner_group.entities after import: 361832
          0
          Devin Kendig
          Developer
          User avatar
          dkendig 
           

          Re: Optimization Tips

          Postby ladyquestio » Wed Mar 12, 2014 3:49 pm

          Whaat wrote:I noticed in that thread about adding geometry to the model that someone tried creating the geometry by writing the mesh out to a temporary file format and then importing presumably with the model.import method. I'll have to try this and see how it compares with fill_from_mesh. 3DS format seems like the logical choice.


          Would XMF or CMF files quailfy under this topic?
          0

          ladyquestio 
           

          Re: Optimization Tips

          Postby tt_su » Thu Mar 13, 2014 11:10 am

          dkendig wrote:woof... just switched from using Entities.add_face to Entities.fill_from_mesh...

          The reason for this is that Entities.add_face does a lot of work. It tries to merge vertices and split edges and faces. For each add_face it does a lot of comparison against all the other entities.

          When you use fill_from_mesh it doesn't do this. It will try to merge points, but that is all it does. If you pre-populate the mesh with PolygonMesh.add_point first and use the indices to generate the polygons it will do even less merging and be even faster.

          Entities.add_* is really best fit for Tools where you add single entities (or small set) each time. When you don't know what geometry might already be in the collection.

          When you populate an empty Entities collection with a large set of entities then fill_from_mesh is the way to go. But it has some limitations that it's difficult to set properties per face and per edge.

          Entities.add_faces_from_mesh is doing the same merging as Entities.add_face.
          0
          User avatar
          tt_su 
          SketchUp Team
          SketchUp Team
           

          Re: Optimization Tips

          Postby Dan Rathbun » Thu Mar 13, 2014 10:03 pm

          Thomas, this information needs to be added into the API dictionary.
          0
            I'm not here much anymore. But a PM will fire email notifications.
            User avatar
            Dan Rathbun 
            PluginStore Author
            PluginStore Author
             

            Re: Optimization Tips

            Postby tt_su » Fri Mar 14, 2014 11:23 am

            Either that or we get the old blog up and running and link more extensive info from the docs to these longer pieces of info. Or some wiki thing. We still working on getting a better system up.
            Got a long list of topics to clarify.
            0
            User avatar
            tt_su 
            SketchUp Team
            SketchUp Team
             

            SketchUcation One-Liner Adverts

            by Ad Machine » 5 minutes ago



            Ad Machine 
            Robot
             

            Previous


             

            Return to Developers' Forum

            Who is online

            Users browsing this forum: draigown and 2 guests

            Visit our sponsors: