/** * When one RunningStat instance is merged into another, the state of the * target RunningInstance should have the state that it would have had if * all the data had been accumulated by it alone. * @covers RunningStat::merge * @covers RunningStat::count */ public function testRunningStatMerge() { $expected = new RunningStat(); foreach ($this->points as $point) { $expected->push($point); } // Split the data into two sets $sets = array_chunk($this->points, floor(count($this->points) / 2)); // Accumulate the first half into one RunningStat object $first = new RunningStat(); foreach ($sets[0] as $point) { $first->push($point); } // Accumulate the second half into another RunningStat object $second = new RunningStat(); foreach ($sets[1] as $point) { $second->push($point); } // Merge the second RunningStat object into the first $first->merge($second); $this->assertEquals(count($first), count($this->points)); $this->assertEquals($first, $expected); }
/** * Update an entry with timing data. * * @param string $name Section name * @param float $elapsedCpu Elapsed CPU time * @param float $elapsedWall Elapsed wall-clock time */ public function updateRunningEntry($name, $elapsedCpu, $elapsedWall) { // If this is the first measurement for this entry, store plain values. // Many profiled functions will only be called once per request. if (!isset($this->mCollated[$name])) { $this->mCollated[$name] = array('cpu' => $elapsedCpu, 'wall' => $elapsedWall, 'count' => 1); return; } $entry =& $this->mCollated[$name]; // If it's the second measurement, convert the plain values to // RunningStat instances, so we can push the incoming values on top. if ($entry['count'] === 1) { $cpu = new RunningStat(); $cpu->push($entry['cpu']); $entry['cpu'] = $cpu; $wall = new RunningStat(); $wall->push($entry['wall']); $entry['wall'] = $wall; } $entry['count']++; $entry['cpu']->push($elapsedCpu); $entry['wall']->push($elapsedWall); }