Viewed   92 times

I had a section in a class that I decided to split into a new one.

When I had ported the code section into a new class I noticed it was considerably slower at executing one of the foreach loops.

I managed to track down part of the problem to be how I decided to save the final result array.

I think it'll be easier to understand if you see a shortened version of my code:

The original ported code: http://pastebin.com/2iBuqmgn More optimized ported code: http://pastebin.com/TYU1rHwU

You'll see that in the first example I manipulate $this->active_topics directly all the way trough.

While in the second example I use local variables before I save the local variable to $this->active_topics AFTER the foreach-loop.

With the original a loop seemed to average to 1 second, while the more optimized one use 0.85 to execute on average. They end up returning exactly the same content.

Why is the more optimized code, with use of local variables, more efficient?

 Answers

3

When you access something in a class the PHP interpreter first has to find the class in memory and then look where the attribute is. On a plain local variable it doesn't need to search the attribute inside the class it can just access the memory of the variable directly and so it is a little faster.

Saturday, October 29, 2022
 
2

none of the above

$firstrun = true;
while(condition)
{
  if($firstrun)
  {
    $firstrun = false;
  }
  else
  {
  }
}

reason I said so, because you are repetitively re-assign false to $firstrun, which you should just do at the first loop

condition test vs assignment which is faster?

for example you have shown, is the same (one execution cycle without some expensive call)

updated

I think condition testing will be slower, cause you might invoke series of subsequent action after that

Thursday, August 11, 2022
4

Instance variable on a class:

class Parent
  @things = []
  def self.things
    @things
  end
  def things
    self.class.things
  end
end

class Child < Parent
  @things = []
end

Parent.things << :car
Child.things  << :doll
mom = Parent.new
dad = Parent.new

p Parent.things #=> [:car]
p Child.things  #=> [:doll]
p mom.things    #=> [:car]
p dad.things    #=> [:car]

Class variable:

class Parent
  @@things = []
  def self.things
    @@things
  end
  def things
    @@things
  end
end

class Child < Parent
end

Parent.things << :car
Child.things  << :doll

p Parent.things #=> [:car,:doll]
p Child.things  #=> [:car,:doll]

mom = Parent.new
dad = Parent.new
son1 = Child.new
son2 = Child.new
daughter = Child.new

[ mom, dad, son1, son2, daughter ].each{ |person| p person.things }
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]

With an instance variable on a class (not on an instance of that class) you can store something common to that class without having sub-classes automatically also get them (and vice-versa). With class variables, you have the convenience of not having to write self.class from an instance object, and (when desirable) you also get automatic sharing throughout the class hierarchy.


Merging these together into a single example that also covers instance variables on instances:

class Parent
  @@family_things = []    # Shared between class and subclasses
  @shared_things  = []    # Specific to this class

  def self.family_things
    @@family_things
  end
  def self.shared_things
    @shared_things
  end

  attr_accessor :my_things
  def initialize
    @my_things = []       # Just for me
  end
  def family_things
    self.class.family_things
  end
  def shared_things
    self.class.shared_things
  end
end

class Child < Parent
  @shared_things = []
end

And then in action:

mama = Parent.new
papa = Parent.new
joey = Child.new
suzy = Child.new

Parent.family_things << :house
papa.family_things   << :vacuum
mama.shared_things   << :car
papa.shared_things   << :blender
papa.my_things       << :quadcopter
joey.my_things       << :bike
suzy.my_things       << :doll
joey.shared_things   << :puzzle
suzy.shared_things   << :blocks

p Parent.family_things #=> [:house, :vacuum]
p Child.family_things  #=> [:house, :vacuum]
p papa.family_things   #=> [:house, :vacuum]
p mama.family_things   #=> [:house, :vacuum]
p joey.family_things   #=> [:house, :vacuum]
p suzy.family_things   #=> [:house, :vacuum]

p Parent.shared_things #=> [:car, :blender]
p papa.shared_things   #=> [:car, :blender]
p mama.shared_things   #=> [:car, :blender]
p Child.shared_things  #=> [:puzzle, :blocks]  
p joey.shared_things   #=> [:puzzle, :blocks]
p suzy.shared_things   #=> [:puzzle, :blocks]

p papa.my_things       #=> [:quadcopter]
p mama.my_things       #=> []
p joey.my_things       #=> [:bike]
p suzy.my_things       #=> [:doll] 
Saturday, August 27, 2022
 
5

Constants defined using define() are fairly slow in PHP. People actually wrote extensions (like hidef) to improve the performance.

But unless you have loads of constants this shouldn't make much of a difference.

As of PHP 5.3 you can also use compile-time constants using const NAME = VALUE;. Those are much faster.

Wednesday, August 3, 2022
 
5

In general, no, editing a global does not make it local:

var myglob = 5;
function incGlob() {
    myglob = myglob + 1;
}

incGlob();
console.log(myglob); // is 6 now

However, if you pass the global variable as an argument, the argument is a local copy:

var myglob = 5;
function incArg(myloc) {
    myloc = myloc + 1;
}

incArg(myglob);
console.log(myglob); // is still 5

Note that objects are passed by reference, so editing the member variables of an argument variable changes the member variables of the original object passed in:

var myglob = { foo:5 };
function editLoc(myloc) {
    myloc.foo = 6;
}

editLoc(myglob);
console.log(myglob.foo); // foo is 6 now

Finally, note that the local variable in editLoc, above, is just a reference. If we try to overwrite the entire object (instead of a member variable), the function simply loses the reference to the original object:

var myglob = { foo:5 };
function clobberLoc(myloc) {
    myloc = { bar:7 };
}

clobberLoc(myglob);
console.log(myglob.foo); // myglob is unchanged...
// ...because clobberLoc didn't alter the object,
// it just overwrote its reference to the object stored in myglob 
Friday, August 26, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :