Optimization Tips
-
@thomthom said:
i += 1
vsi = i.next
i=0; t=Time.now; 10000000.times { i+=1 }; Time.now-t
2.045
i=0; t=Time.now; 10000000.times { i=i.next }; Time.now-t
1.682So avoid
i='0'; t=Time.now; 10000000.times { i.next! }; Time.now-t
~8.300 -
@thomthom said:
That would mean it's not the each loop itself that's slow - but the creation of variables.
range = (0..10000000)
t=Time.now; range.each { |i| x = i + 1 }; Time.now-t
3.402t=Time.now; x=0; range.each { |i| x = i + 1 }; Time.now-t
2.848t=Time.now; x=0; i=0; range.each { |i| x = i + 1 }; Time.now-t
2.39t=Time.now; for j in range; y = j + 1; end; Time.now-t
2.196t=Time.now; y=0; for j in range; y = j + 1; end; Time.now-t
2.186If one has to use blocks, init the variables you use inside the block first.
-
I have read all you optimisation tips and tried them, but nothing seems to change the speed creation of my objects. I'm using Sketchup 8 to create dominos described by a picture. To create the dominos, I tried the add_face method and the fill_from_mesh, but the times are exactly the same. It takes me about 2 s to create 400 pieces, and it's growing exponentially. With 600 pieces -> 7s, 1200 pcs -> 50s...
Is it normal to take so much time ? Each domino is created in his own group for the moment, but it doesn't change if I create them directly in my scene. -
@dany67300 said:
I have read all you optimization tips and tried them, but nothing seems to change the speed creation of my objects. I'm using Sketchup 8 to create dominoes described by a picture. To create the dominoes, I tried the add_face method and the fill_from_mesh, but the times are exactly the same. It takes me about 2 s to create 400 pieces, and it's growing exponentially. With 600 pieces -> 7s, 1200 pces -> 50s...
Is it normal to take so much time ? Each domino is created in his own group for the moment, but it doesn't change if I create them directly in my scene.Since all dominoes are fixed by there number pattern, why not make the set as separate SKPs with common origins.
Then load them into the model when you run the script - no need to make geometry at all - and 'entities.add_instance(defn, trans)
' of them as needed - the transformation used when adding determines the location and rotation.
Because they are each component instances you can swap one type for another as you wish - in codeinstance.definition=xxxx
...
IF you only have one simple block domino make one definition and add_instances of that multiple times... You can apply different materials separately to each instance... -
I hadn't seen that i could put a different material to each instance of a same defintion
thanks a lot ! it works very well -
@dany67300 said:
It takes me about 2 s to create 400 pieces, and it's growing exponentially. With 600 pieces -> 7s, 1200 pcs -> 50s...
Is it normal to take so much time ? Each domino is created in his own group for the moment, but it doesn't change if I create them directly in my scene.I've noticed that sketchup slows down greatly once the number of groups in the current tier is greater than 1000 on my machine. Does your script speed up if the geometry is written straight to
Sketchup.active_model.entities
? -
@bentleykfrog said:
@dany67300 said:
It takes me about 2 s to create 400 pieces, and it's growing exponentially. With 600 pieces -> 7s, 1200 pcs -> 50s...
Is it normal to take so much time ? Each domino is created in his own group for the moment, but it doesn't change if I create them directly in my scene.I've noticed that sketchup slows down greatly once the number of groups in the current tier is greater than 1000 on my machine. Does your script speed up if the geometry is written straight to
Sketchup.active_model.entities
?Adding entities to SketchUp slows down in direct proportion to how many existing entities there is in the entities collection you add to.
-
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 -
The for loop should be faster, try:
` t = Time.now
for i in range docode here
end
puts Time.now - t` -
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 tox
variable so the number of edge clock needed is greater... IMOEdit: 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 thatfor
loop is better theneach
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...
-
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
-
@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
-
Actually we cannot close inspectors singly. Once they are open, we can only collapse or expand them.
-
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 thentoggleRollUp("Outliner")
to roll it up if it's down etc... -
@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
-
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... -
Page 152
http://www.slideshare.net/tenderlove/zomg-why-is-this-code-so-slowattr_accessor :property
vsdef 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
-
That would be in the sub-catagory of load optimization.
However, later is there any difference when instances are instantiated ??
-
What do you mean?
-
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.)
Advertisement