Skip to content

Commit 37d9953

Browse files
author
Rob Caiger
committed
Speed improvements when using xdebug
- Init data by running xdebug with 'unused' and 'dead code' flags on all whitelist files - Run xdebug without flags for each test method - Cache num lines check for each file, to prevent superflous checks
1 parent 12259bb commit 37d9953

File tree

5 files changed

+65
-62
lines changed

5 files changed

+65
-62
lines changed

src/CodeCoverage.php

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class PHP_CodeCoverage
5454

5555
/**
5656
* @var bool
57+
*
58+
* @deprecated
5759
*/
5860
private $processUncoveredFilesFromWhitelist = false;
5961

@@ -86,6 +88,13 @@ class PHP_CodeCoverage
8688
*/
8789
private $tests = [];
8890

91+
/**
92+
* Store all uncovered files
93+
*
94+
* @var array
95+
*/
96+
private $uncoveredFiles = array();
97+
8998
/**
9099
* Constructor.
91100
*
@@ -105,6 +114,8 @@ public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCove
105114

106115
$this->driver = $driver;
107116
$this->filter = $filter;
117+
118+
$this->initData();
108119
}
109120

110121
/**
@@ -213,7 +224,7 @@ public function start($id, $clear = false)
213224

214225
$this->currentId = $id;
215226

216-
$this->driver->start();
227+
$this->driver->start(false);
217228
}
218229

219230
/**
@@ -244,6 +255,12 @@ public function stop($append = true, $linesToBeCovered = [], array $linesToBeUse
244255
$data = $this->driver->stop();
245256
$this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
246257

258+
foreach (array_keys($data) as $file) {
259+
if (isset($this->uncoveredFiles[$file])) {
260+
unset($this->uncoveredFiles[$file]);
261+
}
262+
}
263+
247264
$this->currentId = null;
248265

249266
return $data;
@@ -566,7 +583,7 @@ private function applyIgnoredLinesFilter(array &$data)
566583
private function initializeFilesThatAreSeenTheFirstTime(array $data)
567584
{
568585
foreach ($data as $file => $lines) {
569-
if ($this->filter->isFile($file) && !isset($this->data[$file])) {
586+
if ($this->filter->isFile($file) && !isset($this->data[$file]) && !$this->filter()->isFiltered($file)) {
570587
$this->data[$file] = [];
571588

572589
foreach ($lines as $k => $v) {
@@ -581,62 +598,15 @@ private function initializeFilesThatAreSeenTheFirstTime(array $data)
581598
*/
582599
private function addUncoveredFilesFromWhitelist()
583600
{
584-
$data = [];
585-
$uncoveredFiles = array_diff(
586-
$this->filter->getWhitelist(),
587-
array_keys($this->data)
588-
);
601+
$data = [];
589602

590-
foreach ($uncoveredFiles as $uncoveredFile) {
591-
if (!file_exists($uncoveredFile)) {
592-
continue;
593-
}
594-
595-
if ($this->processUncoveredFilesFromWhitelist) {
596-
$this->processUncoveredFileFromWhitelist(
597-
$uncoveredFile,
598-
$data,
599-
$uncoveredFiles
600-
);
601-
} else {
602-
$data[$uncoveredFile] = [];
603-
604-
$lines = count(file($uncoveredFile));
605-
606-
for ($i = 1; $i <= $lines; $i++) {
607-
$data[$uncoveredFile][$i] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED;
608-
}
609-
}
603+
foreach (array_keys($this->uncoveredFiles) as $file) {
604+
$data[$file] = $this->data[$file];
610605
}
611606

612607
$this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
613608
}
614609

615-
/**
616-
* @param string $uncoveredFile
617-
* @param array $data
618-
* @param array $uncoveredFiles
619-
*/
620-
private function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles)
621-
{
622-
$this->driver->start();
623-
include_once $uncoveredFile;
624-
$coverage = $this->driver->stop();
625-
626-
foreach ($coverage as $file => $fileCoverage) {
627-
if (!isset($data[$file]) &&
628-
in_array($file, $uncoveredFiles)) {
629-
foreach (array_keys($fileCoverage) as $key) {
630-
if ($fileCoverage[$key] == PHP_CodeCoverage_Driver::LINE_EXECUTED) {
631-
$fileCoverage[$key] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED;
632-
}
633-
}
634-
635-
$data[$file] = $fileCoverage;
636-
}
637-
}
638-
}
639-
640610
/**
641611
* Returns the lines of a source file that should be ignored.
642612
*
@@ -909,4 +879,22 @@ private function selectDriver()
909879
return new PHP_CodeCoverage_Driver_Xdebug;
910880
}
911881
}
882+
883+
/**
884+
* Initialise the data with the executable/dead lines from each file in the whitelist
885+
*/
886+
private function initData()
887+
{
888+
foreach ($this->filter()->getWhitelist() as $file) {
889+
$this->driver->start();
890+
include_once($file);
891+
$data = $this->driver->stop();
892+
893+
$this->initializeFilesThatAreSeenTheFirstTime($data);
894+
}
895+
896+
foreach (array_keys($this->data) as $file) {
897+
$this->uncoveredFiles[$file] = 1;
898+
}
899+
}
912900
}

src/CodeCoverage/Driver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ interface PHP_CodeCoverage_Driver
3636
/**
3737
* Start collection of code coverage information.
3838
*/
39-
public function start();
39+
public function start($determineUnusedAndDead = true);
4040

4141
/**
4242
* Stop collection of code coverage information.

src/CodeCoverage/Driver/HHVM.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class PHP_CodeCoverage_Driver_HHVM extends PHP_CodeCoverage_Driver_Xdebug
1919
/**
2020
* Start collection of code coverage information.
2121
*/
22-
public function start()
22+
public function start($determineUnusedAndDead = true)
2323
{
2424
xdebug_start_code_coverage();
2525
}

src/CodeCoverage/Driver/PHPDBG.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function __construct()
3737
/**
3838
* Start collection of code coverage information.
3939
*/
40-
public function start()
40+
public function start($determineUnusedAndDead = true)
4141
{
4242
phpdbg_start_oplog();
4343
}

src/CodeCoverage/Driver/Xdebug.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
*/
1717
class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver
1818
{
19+
/**
20+
* Cache the number of lines for each file
21+
*
22+
* @var array
23+
*/
24+
private $cacheNumLines = [];
25+
1926
/**
2027
* Constructor.
2128
*/
@@ -36,9 +43,13 @@ public function __construct()
3643
/**
3744
* Start collection of code coverage information.
3845
*/
39-
public function start()
46+
public function start($determineUnusedAndDead = true)
4047
{
41-
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
48+
if ($determineUnusedAndDead) {
49+
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
50+
} else {
51+
xdebug_start_code_coverage();
52+
}
4253
}
4354

4455
/**
@@ -85,13 +96,17 @@ private function cleanup(array $data)
8596
*/
8697
private function getNumberOfLinesInFile($file)
8798
{
88-
$buffer = file_get_contents($file);
89-
$lines = substr_count($buffer, "\n");
99+
if (!isset($this->cacheNumLines[$file])) {
100+
$buffer = file_get_contents($file);
101+
$lines = substr_count($buffer, "\n");
102+
103+
if (substr($buffer, -1) !== "\n") {
104+
$lines++;
105+
}
90106

91-
if (substr($buffer, -1) !== "\n") {
92-
$lines++;
107+
$this->cacheNumLines[$file] = $lines;
93108
}
94109

95-
return $lines;
110+
return $this->cacheNumLines[$file];
96111
}
97112
}

0 commit comments

Comments
 (0)