sketchucation logo sketchucation
    • Login
    ⌛ Sale Ending | 30% Off Profile Builder 4 ends 30th September

    Optimization Tips

    Scheduled Pinned Locked Moved Developers' Forum
    110 Posts 22 Posters 169.0k Views 22 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S Offline
      sm4rt
      last edited by

      Well I got a situation !! 😲

      C:\>ruby test.rb range = (0..90000000) t=Time.now; x=0; i=0; range.each { |i| x = 0b0011_1100<<2 }; Time.now-t 13.156753 t=Time.now; x=0; i=0; range.each { |i| x = 60*4 }; Time.now-t 10.400594

      just a no sens !!!
      Really a human oriented language 😉

      1 Reply Last reply Reply Quote 0
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        The for loop should be faster, try:

        ` t = Time.now
        for i in range do

        code here

        end
        puts Time.now - t`

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • S Offline
          sm4rt
          last edited by

          Was talking about shifting binary number is longer then the same "base 10" arithmetic operation...

          Which is no sense in processor calculation.
          Try the same comparison in ASM, C++, PHP etc. and look the result^^

          But in this case I think it's because x = 0b0011_1100<<2 affect the decimal number of the binary one to x variable so the number of edge clock needed is greater... IMO

          Edit: And for loop isn't for me Result-for-each-variables.txt
          here is my results of the test that ThomThom put above to prove that for loop is better then each one and that declaring variable before is faster too but it's still not true for my equipment...
          (Ruby 1.9.2-p180 / Windows 7 64 bit / Intel Core i3 M 350 2.27GHz)

          So I think that these optimizations depend of many variables....(versions of Ruby/Sketchup) Even if some will still be true in the future...

          1 Reply Last reply Reply Quote 0
          • AdamBA Offline
            AdamB
            last edited by

            Here's another to look out for. There is a (time) cost associated with "creating" a variable, so its often faster to use variables declared outside the scope of the executing block.

            def doit
            	
                    start = Time.now
            	10000.times {
            		c = 5
            		d = 5
            		
            		e = c + d
            	}
            	puts Time.now - start
            	
            	a = 0
            	b = 0
            	c = 0
            	start = Time.now
            	10000.times {
            		a = 5
            		b = 5
            		
            		c = a + b
            	}
            	puts Time.now - start
            
            end
            

            Developer of LightUp Click for website

            1 Reply Last reply Reply Quote 0
            • G Offline
              glro
              last edited by

              @dan rathbun said:

              @dan rathbun said:

              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

              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

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

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

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by

                  For Windows windows only - using Win32API.so - which you'll need to 'require'...
                  You can 'close' just one window thus:
                  closeWindow("Outliner")
                  where:

                  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:

                  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:

                  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...

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • G Offline
                    glro
                    last edited by

                    @dan rathbun said:

                    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

                    1 Reply Last reply Reply Quote 0
                    • TIGT Offline
                      TIG Moderator
                      last edited by

                      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...

                      TIG

                      1 Reply Last reply Reply Quote 0
                      • thomthomT Offline
                        thomthom
                        last edited by

                        Page 152
                        http://www.slideshare.net/tenderlove/zomg-why-is-this-code-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-rubyconf2010-zomg-why-is-this-code-so-slow

                        Thomas Thomassen — SketchUp Monkey & Coding addict
                        List of my plugins and link to the CookieWare fund

                        1 Reply Last reply Reply Quote 0
                        • Dan RathbunD Offline
                          Dan Rathbun
                          last edited by

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

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

                          ❓

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • thomthomT Offline
                            thomthom
                            last edited by

                            What do you mean?

                            Thomas Thomassen — SketchUp Monkey & Coding addict
                            List of my plugins and link to the CookieWare fund

                            1 Reply Last reply Reply Quote 0
                            • Dan RathbunD Offline
                              Dan Rathbun
                              last edited by

                              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.)

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • thomthomT Offline
                                thomthom
                                last edited by

                                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.

                                Thomas Thomassen — SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 Reply Last reply Reply Quote 0
                                • Dan RathbunD Offline
                                  Dan Rathbun
                                  last edited by

                                  I did.. It is not clear.

                                  I'm not here much anymore.

                                  1 Reply Last reply Reply Quote 0
                                  • thomthomT Offline
                                    thomthom
                                    last edited by

                                    @dan rathbun said:

                                    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).

                                    Thomas Thomassen — SketchUp Monkey & Coding addict
                                    List of my plugins and link to the CookieWare fund

                                    1 Reply Last reply Reply Quote 0
                                    • jolranJ Offline
                                      jolran
                                      last edited by

                                      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.

                                      1 Reply Last reply Reply Quote 0
                                      • thomthomT Offline
                                        thomthom
                                        last edited by

                                        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...

                                        Thomas Thomassen — SketchUp Monkey & Coding addict
                                        List of my plugins and link to the CookieWare fund

                                        1 Reply Last reply Reply Quote 0
                                        • jolranJ Offline
                                          jolran
                                          last edited by

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

                                          I was doing the condition inside a for loop.

                                          @unknownuser said:

                                          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 😳

                                          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.

                                          1 Reply Last reply Reply Quote 0
                                          • dkendigD Offline
                                            dkendig
                                            last edited by

                                            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

                                            Devin Kendig
                                            Developer

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 3
                                            • 4
                                            • 5
                                            • 6
                                            • 3 / 6
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement