Permalink
Browse files

Optimizations across all implementations

  • Loading branch information...
1 parent 42c2174 commit d30bb4531f4acafc7c413d1c669bbf0490412a12 @KieranP committed Nov 17, 2011
Showing with 82 additions and 80 deletions.
  1. +6 −6 README.textile
  2. +12 −11 javascript/game.js
  3. +12 −11 javascript/test.js
  4. +19 −22 php/game.php
  5. +12 −11 php/test.php
  6. +9 −8 ruby/game.rb
  7. +12 −11 ruby/test.rb
View
@@ -10,9 +10,9 @@ h2. Speed Results
*Note 2:* The times were calculated by averaging the times from ticks 2 through 11 (tick 1 is ignored because of cache warm up).
-=. |_. Place|_. Language |_. Tick Time|_. Render Time|_. % slower than 1st place|_. Notes |
-=. |1st. |Javascript |0.014s |0.004s | |Chrome 16.0.912.36|
-=. |1st. |Javascript |0.024s |0.005s |61.1% |Firefox 8.0 |
-=. |2nd. |Ruby |0.027s |0.014s |127.8% |Ruby 1.9.3p0 |
-=. |2nd. |Ruby |0.035s |0.015s |177.8% |Ruby 1.9.2p290 |
-=. |3rd. |PHP |0.107s |0.023s |622.2% |PHP 5.3.6 |
+=. |_. Place|_. Language |_. Tick Time|_. Render Time|_. % slower than 1st place|_. Notes |
+=. |1st. |Javascript |0.011s |0.003s | |V8 3.6.6.8 |
+=. |2nd. |Javascript |0.019s |0.005s |71.4% |Firefox 8.0 |
+=. |3rd. |Ruby |0.017s |0.015s |128.5% |Ruby 1.9.3p0 |
+=. |4th. |Ruby |0.023s |0.019s |200.0% |Ruby 1.9.2p290|
+=. |5th. |PHP |0.085s |0.023s |671.4% |PHP 5.3.6 |
View
@@ -19,33 +19,33 @@ World.prototype.cell_at = function(x, y) {
return this.cells[x+'-'+y];
}
-World.prototype.neighbours_at = function(x, y) {
- if (!this.neighbours[x+'-'+y]) {
- this.neighbours[x+'-'+y] = new Array;
+World.prototype.neighbours_around = function(cell) {
+ if (!this.neighbours[cell.key]) {
+ this.neighbours[cell.key] = new Array;
$.each(this.directions, function(i, set) {
- var cell = this.cell_at((x + set[0]), (y + set[1]));
- if (cell) { this.neighbours[x+'-'+y].push(cell); }
+ var neighbour = this.cell_at((cell.x + set[0]), (cell.y + set[1]));
+ if (neighbour) { this.neighbours[cell.key].push(neighbour); }
}.bind(this));
}
- return this.neighbours[x+'-'+y];
+ return this.neighbours[cell.key];
}
-World.prototype.alive_neighbours_at = function(x, y) {
- return $.grep(this.neighbours_at(x, y), function(cell) {
+World.prototype.alive_neighbours_around = function(cell) {
+ return $.grep(this.neighbours_around(cell), function(cell) {
return !cell.dead;
- });
+ }).length;
}
World.prototype._tick = function(x, y) {
var cells = $.map(this.cells, function(cell) { return cell; });
// First determine the action for all cells
$.each(cells, function(i, cell) {
- var alive_neighbours = this.alive_neighbours_at(cell.x, cell.y).length;
+ var alive_neighbours = this.alive_neighbours_around(cell);
if (cell.dead && alive_neighbours == 3) {
cell.next_action = 'revive';
- } else if ($.inArray(alive_neighbours, [2,3]) == -1) {
+ } else if (alive_neighbours < 2 || alive_neighbours > 3) {
cell.next_action = 'kill';
}
}.bind(this));
@@ -100,6 +100,7 @@ World.prototype.boundaries = function() {
function Cell(x, y, dead) {
this.x = x;
this.y = y;
+ this.key = (x+'-'+y);
this.dead = (dead || false);
this.next_action = null;
}
View
@@ -37,7 +37,7 @@ $(document).ready(function() {
var world = new World;
var cell1 = world.add_cell(0, 0);
var cell2 = world.add_cell(0, 1);
- ok($.inArray(cell2, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell2, world.neighbours_around(cell1)) > -1);
equal($.isEmptyObject(world.neighbours), false);
var cell3 = world.add_cell(1, 0);
@@ -47,29 +47,31 @@ $(document).ready(function() {
test("can retrieve neighbours for a given location", function() {
var world = new World;
+ var center_cell = world.add_cell(0, 0);
+
var cell = world.add_cell(0, 1);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(1, 1, true);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(1, 0);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(1, -1, true);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(0, -1);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(-1, -1, true);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(-1, 0);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
var cell = world.add_cell(-1, 1, true);
- ok($.inArray(cell, world.neighbours_at(0, 0)) > -1);
+ ok($.inArray(cell, world.neighbours_around(center_cell)) > -1);
});
test("an retrieve alive neighbours for a given location", function() {
@@ -78,8 +80,7 @@ $(document).ready(function() {
var cell1 = world.add_cell(0, 0);
var cell2 = world.add_cell(0, 1);
var cell3 = world.add_cell(1, 0, true);
- ok($.inArray(cell2, world.alive_neighbours_at(0, 0)) > -1);
- ok($.inArray(cell3, world.alive_neighbours_at(0, 0)) == -1);
+ equal(world.alive_neighbours_around(cell1), 1);
});
test("can tick along", function() {
View
@@ -16,8 +16,7 @@ function add_cell($x, $y, $dead = false) {
if ($this->cell_at($x, $y)) {
throw new LocationOccupied;
}
- unset($this->neighbours);
- unset($this->boundaries);
+ unset($this->neighbours, $this->boundaries);
return $this->cells["$x-$y"] = new Cell($x, $y, $dead);
}
@@ -27,43 +26,40 @@ function cell_at($x, $y) {
}
}
- function neighbours_at($x, $y) {
- if (!isset($this->neighbours["$x-$y"])) {
- $this->neighbours["$x-$y"] = array();
+ function neighbours_around($cell) {
+ if (!isset($this->neighbours[$cell->key])) {
+ $this->neighbours[$cell->key] = array();
foreach ($this->directions as $set) {
- $cell = $this->cell_at(($x + $set[0]), ($y + $set[1]));
- if ($cell) { array_push($this->neighbours["$x-$y"], $cell); }
+ $neighbour = $this->cell_at(($cell->x + $set[0]), ($cell->y + $set[1]));
+ if ($neighbour) { $this->neighbours[$cell->key][] = $neighbour; }
}
}
-
- return $this->neighbours["$x-$y"];
+ return $this->neighbours[$cell->key];
}
- function alive_neighbours_at($x, $y) {
- $alive_neighbours = array();
- foreach ($this->neighbours_at($x, $y) as $cell) {
+ function alive_neighbours_around($cell) {
+ $alive_neighbours = 0;
+ foreach ($this->neighbours_around($cell) as $cell) {
if (!$cell->dead) {
- $alive_neighbours[] = $cell;
+ $alive_neighbours++;
}
}
return $alive_neighbours;
}
function tick() {
- $cells = array_values($this->cells);
-
// First determine the action for all cells
- foreach ($cells as $cell) {
- $alive_neighbours = count($this->alive_neighbours_at($cell->x, $cell->y));
+ foreach ($this->cells as $cell) {
+ $alive_neighbours = $this->alive_neighbours_around($cell);
if ($cell->dead && $alive_neighbours == 3) {
$cell->next_action = 'revive';
- } else if (!in_array($alive_neighbours, array(2,3))) {
+ } else if ($alive_neighbours < 2 || $alive_neighbours > 3) {
$cell->next_action = 'kill';
}
}
// Then execute the determined action for all cells
- foreach ($cells as $cell) {
+ foreach ($this->cells as $cell) {
if ($cell->next_action == 'revive') {
$cell->dead = false;
} else if ($cell->next_action == 'kill') {
@@ -90,8 +86,8 @@ function boundaries() {
if (!isset($this->boundaries)) {
$x_vals = $y_vals = array();
foreach ($this->cells as $cell) {
- array_push($x_vals, $cell->x);
- array_push($y_vals, $cell->y);
+ $x_vals[] = $cell->x;
+ $y_vals[] = $cell->y;
}
$this->boundaries = array(
@@ -113,11 +109,12 @@ function boundaries() {
class Cell {
- var $x, $y, $dead, $next_action;
+ var $x, $y, $key, $dead, $next_action;
function __construct($x, $y, $dead = false) {
$this->x = $x;
$this->y = $y;
+ $this->key = "$x-$y";
$this->dead = $dead;
}
View
@@ -42,45 +42,46 @@ function test_can_retrieve_cells_at_a_given_location() {
function test_resets_neighbours_data_when_adding_cells() {
$cell1 = $this->world->add_cell(0, 0);
$cell2 = $this->world->add_cell(0, 1);
- $this->assertTrue(in_array($cell2, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell2, $this->world->neighbours_around($cell1)));
$this->assertFalse(empty($this->world->neighbours));
$cell3 = $this->world->add_cell(1, 0);
$this->assertTrue(empty($this->world->neighbours));
}
function test_can_retrieve_neighbours_for_a_given_location() {
+ $center_cell = $this->world->add_cell(0, 0);
+
$cell = $this->world->add_cell(0, 1);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(1, 1, true);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(1, 0);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(1, -1, true);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(0, -1);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(-1, -1, true);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(-1, 0);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
$cell = $this->world->add_cell(-1, 1, true);
- $this->assertTrue(in_array($cell, $this->world->neighbours_at(0, 0)));
+ $this->assertTrue(in_array($cell, $this->world->neighbours_around($center_cell)));
}
function test_can_retrieve_alive_neighbours_for_a_given_location() {
$cell1 = $this->world->add_cell(0, 0);
$cell2 = $this->world->add_cell(0, 1);
$cell3 = $this->world->add_cell(1, 0, true);
- $this->assertTrue(in_array($cell2, $this->world->alive_neighbours_at(0, 0)));
- $this->assertFalse(in_array($cell3, $this->world->alive_neighbours_at(0, 0)));
+ $this->assertEqual($this->world->alive_neighbours_around($cell1), 1);
}
function test_can_tick_along() {
View
@@ -19,27 +19,27 @@ def cell_at(x, y)
@cells["#{x}-#{y}"]
end
- def neighbours_at(x, y)
- @neighbours["#{x}-#{y}"] ||= begin
+ def neighbours_around(cell)
+ @neighbours[cell.key] ||= begin
@directions.collect { |rel_x, rel_y|
- self.cell_at((x + rel_x), (y + rel_y))
+ self.cell_at((cell.x + rel_x), (cell.y + rel_y))
}.compact
end
end
- def alive_neighbours_at(x, y)
- neighbours_at(x, y).reject(&:dead)
+ def alive_neighbours_around(cell)
+ neighbours_around(cell).reject(&:dead).size
end
def tick!
cells = @cells.values
# First determine the action for all cells
cells.each do |cell|
- alive_neighbours = self.alive_neighbours_at(cell.x, cell.y).size
+ alive_neighbours = self.alive_neighbours_around(cell)
if cell.dead && alive_neighbours == 3
cell.next_action = :revive
- elsif !(2..3).include?(alive_neighbours)
+ elsif alive_neighbours < 2 || alive_neighbours > 3
cell.next_action = :kill
end
end
@@ -86,11 +86,12 @@ def boundaries
class Cell
- attr_accessor :x, :y, :dead, :next_action
+ attr_accessor :x, :y, :key, :dead, :next_action
def initialize(x, y, dead = false)
@x = x
@y = y
+ @key = "#{x}-#{y}"
@dead = dead
end
View
@@ -36,45 +36,46 @@
it "resets neighbours data when adding cells" do
cell1 = world.add_cell(0, 0)
cell2 = world.add_cell(0, 1)
- world.neighbours_at(0, 0).should include cell2
+ world.neighbours_around(cell1).should include cell2
world.neighbours.should_not be_empty
cell3 = world.add_cell(1, 0)
world.neighbours.should be_empty
end
it "can retrieve neighbours for a given location" do
+ center_cell = world.add_cell(0, 0)
+
cell = world.add_cell(0, 1)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(1, 1, true)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(1, 0)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(1, -1, true)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(0, -1)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(-1, -1, true)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(-1, 0)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
cell = world.add_cell(-1, 1, true)
- world.neighbours_at(0, 0).should include cell
+ world.neighbours_around(center_cell).should include cell
end
it "can retrieve alive neighbours for a given location" do
cell1 = world.add_cell(0, 0)
cell2 = world.add_cell(0, 1)
cell3 = world.add_cell(1, 0, true)
- world.alive_neighbours_at(0, 0).should include cell2
- world.alive_neighbours_at(0, 0).should_not include cell3
+ world.alive_neighbours_around(cell1).should eq 1
end
it "can tick along" do

0 comments on commit d30bb45

Please sign in to comment.