RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
[RESOLVED] Equivalent Constructions?

0 Members and 1 Guest are viewing this topic.

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
Code: [Select]
for i in 0...array.size
  p array[i]
end

Hey, I know that this is an inefficient way to act upon every element in an array, and I know that this is better:

Code: [Select]
array.each {|i| print i}

What I was wondering was two things:

(1)

Is this:

Code: [Select]
for i in array
  print i
end

equivalent to the .each way? Or is it done in a different way? And

(2) Is there a way in the .each method to retrieve the current element's index?

i.e. If you don't want to print out i but instead print out index, i. For purposes of demonstrating what I mean, this would be done like the following by the first method of acting on every element of the array

Code: [Select]
for i in 0...array.size
  p i, array[i]
end
« Last Edit: January 31, 2008, 04:05:51 PM by modern algebra »

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
(1)
My guess is that it is faster than the for i in 0...array.size while slower than the .each method.
My reasoning:
Code: [Select]
for i in 0...array.size
  p array[i]
end

# Is pretty much equivalent to
(0...array.size).each {|i| p array[i]}
There are probably some variable scope issues if you tried that code, but you should get the idea.
You iterator over another object to get an object which is then used to retrieve an object from the array.

Accordingly to Blizzard the .each is faster than using a for loop. How fast and if the different is significant I do not know. Though considering the different scope I can easily imagine that using .each is faster.

(2)
There is no direct way to retrieve the index. You can use array.index(i) to retrieve the index, but not only is that slow, it only returns the index of the first matching value. Searching for elements in an array is so slow that in almost all cases using the for i in 0...array.size way is faster. In addition it is easier to manage and keep track of.
Only use the iterator way (for element in array) if the index is irrelevant.

If the index is relevant then you could this:
Code: [Select]
array.each_with_index {|element, index| p index, element}


If you want to know the .each method is implemented as the Visitor Pattern
It can be used on any Enumerable collection.
There exist collections where the order the elements are retrieved can be stochastic and some where the concept of indexes doesn't make sense.
The index with the .each_with_index method shows how many elements was retrieved before it.

*hugs*
 - Zeriab

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
Cool. Thanks; that answered my question perfectly. You're awesome, Zeriab  :D

I didn't know about .each_with_index either. Thanks again.

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
How you conduct a test on the speed of the different constructions?
I want to know how fast each construction runs. I want you test this.
I am sure it will be a useful experience ^^

So, how do you plan to do it?
In addition to put forward the average speed difference you should explain how the tests was conduct in a convincing way.
Sort of the proof that you have done your work properly.

Good luck
*hugs*
 - Zeriab

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
*cries

I suppose I would try this:

Take an arbitrarily large array, and apply each construction successively (each doing the same thing; not print statements for sure :P). Upon completion of each construction's algorithm, record the time taken for the algorithm to complete.

Maybe I should try this for various types of algorithms - some simple, some heavy, some requiring index. I should also probably keep track of CPU Usage.


*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
Try it. Tell me how it went.
If you learned anything, tell me that as well

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
Failure :P

I tried this code:

Code: [Select]
class Test_Object
  attr_reader :id
  attr_reader :test_variable
  def initialize (id)
    @id = id
    @test_variable = 0
  end
  def test
    # This is just a random method call
    @test_variable += 1
  end
end


class Test
  def initialize
    test_array = []
    for i in 0...1200000
      test_array.push (Test_Object.new (i))
    end
    p 'Test A Begins'
    for i in 0...test_array.size
      test_array[i].test
    end
    p 'Test A Completed'
    p 'Test B begins'
    for i in test_array
      i.test
    end
    p 'Test B completed'
    p 'Test C begins'
    test_array.each {|i| i.test}
    p 'Test C completed'
  end
end

Under the basic idea that the best test would be to do the same thing to each of the items in the array. However, for large large numbers, the script would hang on the first part. For smaller numbers (like 1200000), the tests would complete so quickly as to make it nearly impossible to time to any degree of precision. That being said, the first two performed in roughly the same time (slightly less than 2 seconds) and the 3rd was faster (about a second or less)

I will try to find a better way to test the script that hopefully will not hang at the first part.

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
I suggest you do a Graphics.update between each test.
The script-hanging error comes when Graphics.update isn't called after a certain amount of time.
You can just use the system time to figure out the differences in time from before and after the test. (http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_time.html)
Store the results of each run.

Run the test a decent amount of times. Let's just say 30 or 50. Whatever you find suitable.
Give a schema of the test results and draw conclusions out from the schema.

Good luck ^_^

Edit: Btw. would this test code be reliable? (Note: I didn't include time because you have to figure that part out yourself ;))
I use algorithms with a complexity of n2 instead of n.
Code: [Select]
class Test_Object
  attr_reader :id
  attr_reader :test_variable
  def initialize (id)
    @id = id
    @test_variable = 0
  end
  def test
    # This is just a random method call
    @test_variable += 1
  end
end


class Test
  def initialize
    test_array = Array.new(2000)
    for i in 0...test_array.size
      test_array[i] = Test_Object.new(i)
    end
    p 'Test A Begins'
    for i in 0...test_array.size
      for j in 0...test_array.size
        test_array[i].test
      end
    end
    p 'Test A Completed'
    p 'Test B begins'
    for i in test_array
      for j in test_array
        i.test
      end
    end
    p 'Test B completed'
    p 'Test C begins'
    test_array.each {|i| test_array.each{|j| i.test}}
    p 'Test C completed'
  end
end

Test.new
« Last Edit: February 08, 2008, 10:31:09 PM by Zeriab »