• Login
sketchucation logo sketchucation
  • Login
๐Ÿ”Œ Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

[Code] Grepping entities

Scheduled Pinned Locked Moved Developers' Forum
19 Posts 6 Posters 2.4k Views 6 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.
  • T Offline
    thomthom
    last edited by 9 Nov 2012, 09:31

    Notice when I select Edges and Faces it matters what I test for first. The whole collection of entities is nearly all edges. If I test for them first it's just about as fast as just selecting edges - because of short-circuiting.

    But if I test for faces first - which there isn't any of then there's a penalty.

    So test for the most likely cause first!

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

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 9 Nov 2012, 11:44

      @thomthom said:

      @tig said:

      It would need to be something like:
      fs=Sketchup.active_model.entities.grep(Sketchup::Face).select{|f|f.material}
      to get an array of all faces that have a material assigned to them etc.

      But then you do a double iteration. I'd think it's be best to do this as:

      fs=Sketchup.active_model.entities.select{|f|f.is_a?(Sketchup::Face) && f.material}

      That's just one iteration.

      How about this ?

      fs=Sketchup.active_model.entities.grep(Sketchup::Face){|f| f.material ? f : nil }.compact

      compact removes the nil elements afterward.

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • T Offline
        thomthom
        last edited by 9 Nov 2012, 12:14

        Again - a second iteration. Of the result, but none the less - an extra iteration.

        What's interesting here is what the performance is.

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

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 9 Nov 2012, 15:34

          I've looked st a couple of methods in Vertex Tools - where I refactored them to use grep in combo with hashes and I'm getting huge improvements! ๐Ÿ˜„

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

          1 Reply Last reply Reply Quote 0
          • D Offline
            dkendig
            last edited by 9 Nov 2012, 16:02

            Glad I got frustrated on Wednesday and started throwing stuff at the wall to see what stuck! Nice benchmarks Thomthom, hope my find can help some folks out!

            Devin Kendig
            Developer

            1 Reply Last reply Reply Quote 0
            • D Offline
              dkendig
              last edited by 9 Nov 2012, 16:42

              Dan, did you try benchmarking your pattern? It might not have much of a performance hit if you have the extra filtering criteria in the grep block:

              @unknownuser said:

              Donโ€™t forget the extra processing โ€” a map operation โ€” comes โ€œfreeโ€ if you provide grep with a block

              http://www.globalnerdy.com/2008/08/21/enumerating-enumerable-enumerablegrep/

              Devin Kendig
              Developer

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 9 Nov 2012, 18:14

                @dkendig said:

                Dan, did you try benchmarking your pattern?

                No, but it can be added to TT's code above if your interested. (As TT said compact() needs to re-iterate the array to remove the nil elements. I tried using next but the block still returns a nil.)

                And BTW.. I checked the C source for compact() which uses dup() to create a new array, and then calls compact!(), ie %(#008080)[rb_compact_bang()] on the C-side, so to save time, this pattern might as well use the "bang" edition of the method, and save the time to create a new array.

                I'm deep into a Javascript mod for the forums, presently, and not doing much in Ruby.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • T Offline
                  thomthom
                  last edited by 15 Nov 2012, 18:07

                  Can you post your result data as well?

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

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    thomthom
                    last edited by 15 Nov 2012, 18:08

                    And what was the comparison code?

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

                    1 Reply Last reply Reply Quote 0
                    • D Offline
                      dkendig
                      last edited by 15 Nov 2012, 19:34

                      drawing_ele_test time: 0.00999999046325684, resulted in 1103 elements found
                      types_test time: 0.00999999046325684, resulted in 1103 elements found
                      magic_test time: 0.0420000553131104, resulted in 1103 elements found
                      loop_test time: 0.0190000534057617, resulted in 1103 elements found

                      that's my results from the huge one-liner that I copy and pasted for a scene with 13108 total entities. 10,000 edges, 1,000 component instances, 1,000 groups, 1,000 faces. The goal was to find anything that could have a material applied to it, so I wanted to filter out edges.

                      So actually it appears my test was flawed. I'm adding entities to a hash, and looping through the desired types in the "types_test" results. In the "drawing_ele_test" I am just doing a comparison to see if the type matches one of the types I am looking for. They both end up taking the same exact amount of time, so there's probably a cleaner way to write this, but under the hood both of those tests are essentially doing the same thing.

                      Devin Kendig
                      Developer

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        dkendig
                        last edited by 15 Nov 2012, 19:38

                        Just ran a benchmark in a scene with 10,000 edges, one component instance, one face, and one group. It appears that grepping specific classes you are interested in, is faster than doing a more general grep and then comparing within the block.

                        sample code soon to follow

                        Devin Kendig
                        Developer

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          dkendig
                          last edited by 15 Nov 2012, 19:39

                          actually, here's the benchmark code I ran

                          
                          class Magic;def initialize(&block)
                          	@block=block;end
                          	def ===(other)
                          		@block.call(other)
                          	end
                          end
                          
                          def GetVrayImportantArrayFromGrepDrawingelement(entities)
                          	return entities.grep(Sketchup;;Drawingelement){|ent| false == (ent.class == Sketchup;;Edge) ? ent ; nil}.compact
                          end
                          
                          def GetVrayImportantArrayOfTypesFromGrep(entities,typeHash)
                          	for curType in typeHash.keys()
                          		typeHash[curType] = entities.grep(curType )
                          	end
                          end
                          
                          def GetVrayImportantArrayFromGrepMagic(entities)
                          	return entities.grep(Magic.new {|ent| ent if(ent.class == Sketchup;;ComponentInstance or ent.class == Sketchup;;Group or ent.class == Sketchup;;Face)})
                          end
                          
                          def GetVrayImportantArrayFromLoop(entities)
                          	vrayImportant = Array.new()
                          	for ent in entities.to_a
                          		if ent.class == Sketchup;;Face or ent.class == Sketchup;;ComponentInstance or ent.class == Sketchup;;Group
                          			vrayImportant.push(ent)
                          		end
                          	end
                          	return vrayImportant
                          end
                          
                          def RunBenchmarkOnEntities(entities)
                          	testHash = Hash.new()
                          	testHash[Sketchup;;Face] = []
                          	testHash[Sketchup;;ComponentInstance] = []
                          	testHash[Sketchup;;Group] = []
                          	
                          	grep_drawing_ele_result = grep_magic_result = compare_loop_result = nil
                          	
                          	grep_drawing_ele_start_time = Time.now.to_f
                          	grep_drawing_ele_result = GetVrayImportantArrayFromGrepDrawingelement(entities)
                          	grep_drawing_ele_end_time = Time.now.to_f
                          	
                          	grep_types_start_time = Time.now.to_f
                          	grep_types_result = GetVrayImportantArrayOfTypesFromGrep(entities,testHash)
                          	grep_types_end_time = Time.now.to_f
                          	
                          	grep_magic_start_time = Time.now.to_f
                          	grep_magic_result = GetVrayImportantArrayFromGrepMagic(entities)
                          	grep_magic_end_time = Time.now.to_f 
                          	
                          	compare_loop_start_time = Time.now.to_f
                          	compare_loop_result = GetVrayImportantArrayFromLoop(entities)
                          	compare_loop_end_time = Time.now.to_f
                          	
                          	puts "drawing_ele_test time; #{grep_drawing_ele_end_time - grep_drawing_ele_start_time}, resulted in #{grep_drawing_ele_result.size} elements found"
                          	
                          	puts "types_test time; #{grep_types_end_time - grep_types_start_time}, resulted in #{testHash.values.flatten.size} elements found"
                          	
                          	puts "magic_test time; #{grep_magic_end_time - grep_magic_start_time}, resulted in #{compare_loop_result.size} elements found"
                          	
                          	puts "loop_test time; #{compare_loop_end_time - compare_loop_start_time}, resulted in #{compare_loop_result.size} elements found"
                          	
                          	return nil
                          end
                          
                          RunBenchmarkOnEntities(Sketchup.active_model.entities)
                          

                          Devin Kendig
                          Developer

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          1 / 1
                          • First post
                            17/19
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement