sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    Mac User? | Join the Rayscaper Beta for Mac Learn More

    Set.insert vs array << x unless array.include?(x)

    Scheduled Pinned Locked Moved Developers' Forum
    19 Posts 7 Posters 26.3k Views 7 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.
    • thomthomT
      thomthom
      last edited by

      @unknownuser said:

      Will have a look

      Will have a look at that.

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

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

        I'll be damned!
        Very interesting Jernej.

        ...looks like I need to do some more testing of my script and possibly refactor again.

        So while the Array.include? is dead slow - the overhead of hash look-up is still faster than just adding everything into one big pile and so a single filtering afterwards...

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

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

          looking at the .uniq! source code: http://ruby-doc.org/core/classes/Array.src/M002215.html

          
          /*
           *  call-seq;
           *     array.uniq! -> array or nil
           *  
           *  Removes duplicate elements from _self_.
           *  Returns <code>nil</code> if no changes are made (that is, no
           *  duplicates are found).
           *     
           *     a = [ "a", "a", "b", "b", "c" ]
           *     a.uniq!   #=> ["a", "b", "c"]
           *     b = [ "a", "b", "c" ]
           *     b.uniq!   #=> nil
           */
          
          static VALUE
          rb_ary_uniq_bang(ary)
              VALUE ary;
          {
              VALUE hash, v, vv;
              long i, j;
          
              hash = ary_make_hash(ary, 0);
          
              if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) {
                  return Qnil;
              }
              for (i=j=0; i<RARRAY(ary)->len; i++) {
                  v = vv = rb_ary_elt(ary, i);
                  if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
                      rb_ary_store(ary, j++, v);
                  }
              }
              RARRAY(ary)->len = j;
          
              return ary;
          }
          
          

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

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

            Jernej: how about larger iterations and higher number of random values?

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

            1 Reply Last reply
            Reply Quote 0
            • J
              Jernej Vidmar
              last edited by

              How about using Array.uniq! method:

              Test 1
              t=Time.now;a=[];10000000.times{r=rand(10);a<<r unless a.include?(r)};puts Time.now - t
              Result: 12.297
              t=Time.now;a=Set.new;10000000.times{a.insert(rand(10))};puts Time.now - t
              Result: 15.719
              t=Time.now;a=[];10000000.times{r=rand(10);a<<r};a.uniq!; puts Time.now - t
              Result: 7.753

              Test 2
              t=Time.now;a=[];100000.times{r=rand(10000);a<<r unless a.include?(r)};puts Time.now-t
              Result: 40.97
              t=Time.now;a=Set.new;100000.times{a.insert(rand(10000))};puts Time.now-t
              Result: 0.377
              t=Time.now;a=[];100000.times{r=rand(10000);a<<r};a.uniq!;puts Time.now-t
              Result: 0.087

              1 Reply Last reply
              Reply Quote 0
              • J
                Jernej Vidmar
                last edited by

                @thomthom said:

                Jernej: how about larger iterations and higher number of random values?

                t=Time.now;a=Set.new;10000000.times{a.insert(rand(10000))};puts Time.now - t
                Result: 37.911
                t=Time.now;a=[];10000000.times{r=rand(10000);a<<r};a.uniq!; puts Time.now - t
                Result: 8.282

                Still a winner?

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

                  It's refactoring time!

                  Nice find! πŸ‘

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

                  1 Reply Last reply
                  Reply Quote 0
                  • R
                    RickW
                    last edited by

                    That's all great (using .uniq!) until you start dealing with Point3d objects πŸ˜„
                    In that case, always use Set.

                    RickW
                    www.smustard.com

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

                      ....or make all of your Point3d's into arrays so they will sort!/uniq! etc as arrays...

                      TIG

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

                        @tig said:

                        ....or make all of your Point3d's into arrays so they will sort!/uniq! etc as arrays...

                        But is the overhead of converting the Point3d's into arrays and uniq! faster than using a Set?

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

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

                          Who knows ?
                          Time for you to do another test... πŸ˜‰

                          TIG

                          1 Reply Last reply
                          Reply Quote 0
                          • honoluludesktopH
                            honoluludesktop
                            last edited by

                            I probably don't know what I am doing, but I ran the following test, and obtained the attached results. I typically use array.push variable, and don't understand the situations when the other examples might be used. Btw, when I applied the other forms to my app, it failed in ways that leave me to believe that those forms are data sensitive. Can anyone explaine to a Ruby beginner what's up?

                            t=Time.now
                            a=[]
                            100000.times do r=rand(10000)
                              a<<r
                            end
                            a.uniq!
                            puts Time.now-t
                            

                            0.125

                            t=Time.now
                            a=[]
                            100000.times do r=rand(10000)
                              a.push r
                            end
                            a.uniq!
                            puts Time.now-t
                            

                            0.141

                            t=Time.now
                            a=[]
                            100000.times do r=rand(10000)
                              a.push r
                            end
                            puts Time.now-t
                            

                            0.094

                            t=Time.now
                            a=[]
                            100000.times do r=rand(10000)
                              a<<r
                            end
                            puts Time.now-t
                            

                            0.093

                            1 Reply Last reply
                            Reply Quote 0

                            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                            With your input, this post could be even better πŸ’—

                            Register Login
                            • 1 / 1
                            • First post
                              Last post
                            Buy SketchPlus
                            Buy SUbD
                            Buy WrapR
                            Buy eBook
                            Buy Modelur
                            Buy Vertex Tools
                            Buy SketchCuisine
                            Buy FormFonts

                            Advertisement