Skip to content

Commit 6609072

Browse files
Add performance stats
1 parent 8817822 commit 6609072

16 files changed

+3140
-1
lines changed

src/Command/MissingStringsCommand.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
112112
// Show summary statistics
113113
$this->outputSummary($output, $result);
114114

115+
// Show debug information if debug mode is enabled
116+
if ($config->isDebugEnabled()) {
117+
$this->outputDebugInformation($output, $result);
118+
}
119+
115120
return $result->isValid() ? 0 : 1;
116121
}
117122

@@ -150,4 +155,52 @@ private function outputSummary(OutputInterface $output, ValidationResult $result
150155
$output->writeln('<error>✗ Language string validation failed</error>');
151156
}
152157
}
158+
159+
/**
160+
* Output debug performance information.
161+
*
162+
* @param OutputInterface $output the output interface
163+
* @param ValidationResult $result the validation result
164+
*/
165+
private function outputDebugInformation(OutputInterface $output, ValidationResult $result): void
166+
{
167+
$debugData = $result->getDebugData();
168+
169+
$output->writeln('');
170+
$output->writeln('<comment>Debug Performance Information:</comment>');
171+
172+
// Overall timing
173+
if ($debugData['processing_time'] > 0) {
174+
$output->writeln(sprintf('- <info>Total processing time: %.3f seconds</info>', $debugData['processing_time']));
175+
}
176+
177+
// Plugin counts
178+
$totalPlugins = $debugData['plugin_count'] + $debugData['subplugin_count'];
179+
$output->writeln(sprintf('- <info>Plugins processed: %d</info>', $totalPlugins));
180+
if ($debugData['subplugin_count'] > 0) {
181+
$output->writeln(sprintf(' - Main: %d, Subplugins: %d', $debugData['plugin_count'], $debugData['subplugin_count']));
182+
}
183+
184+
// Total files count
185+
if (!empty($debugData['file_counts'])) {
186+
$totalFiles = $debugData['file_counts']['total_files'] ?? 0;
187+
if ($totalFiles > 0) {
188+
$output->writeln(sprintf('- <info>Files processed: %d</info>', $totalFiles));
189+
}
190+
}
191+
192+
// String processing metrics
193+
if (!empty($debugData['string_counts'])) {
194+
$output->writeln('- <info>String processing metrics:</info>');
195+
foreach ($debugData['string_counts'] as $type => $count) {
196+
if ($count > 0) {
197+
/** @var string $type */
198+
$displayName = str_replace('_', ' ', $type);
199+
$output->writeln(sprintf(' - %s: %d', ucfirst($displayName), $count));
200+
}
201+
}
202+
}
203+
204+
$output->writeln('');
205+
}
153206
}

src/MissingStrings/Extractor/StringExtractor.php

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ class StringExtractor
3737
*/
3838
private ?FileDiscovery $fileDiscovery = null;
3939

40+
/**
41+
* String processing metrics.
42+
*
43+
* @var array
44+
*/
45+
private $metrics = [
46+
'extraction_time' => 0.0,
47+
'files_processed' => 0,
48+
'strings_extracted' => 0,
49+
'string_usages_found' => 0,
50+
];
51+
4052
/**
4153
* Constructor.
4254
*/
@@ -72,6 +84,16 @@ public function extractFromPlugin(Plugin $plugin): array
7284
throw new \RuntimeException('File discovery service not set');
7385
}
7486

87+
$startTime = microtime(true);
88+
89+
// Reset metrics for this extraction
90+
$this->metrics = [
91+
'extraction_time' => 0.0,
92+
'files_processed' => 0,
93+
'strings_extracted' => 0,
94+
'string_usages_found' => 0,
95+
];
96+
7597
$allStrings = [];
7698
$filesByCategory = $this->fileDiscovery->getAllFiles();
7799

@@ -97,10 +119,21 @@ public function extractFromPlugin(Plugin $plugin): array
97119
continue;
98120
}
99121

100-
$strings = $extractor->extract($content, $plugin->component, $file);
122+
++$this->metrics['files_processed'];
123+
124+
$strings = $extractor->extract($content, $plugin->component, $file);
125+
126+
// Track string extraction metrics
127+
$this->metrics['strings_extracted'] += count($strings);
128+
foreach ($strings as $stringUsages) {
129+
$this->metrics['string_usages_found'] += count($stringUsages);
130+
}
131+
101132
$allStrings = $this->mergeStringUsages($allStrings, $strings);
102133
}
103134

135+
$this->metrics['extraction_time'] = microtime(true) - $startTime;
136+
104137
return $allStrings;
105138
}
106139

@@ -171,4 +204,14 @@ public function getExtractors(): array
171204
{
172205
return $this->extractors;
173206
}
207+
208+
/**
209+
* Get string processing performance metrics.
210+
*
211+
* @return array performance metrics for string extraction
212+
*/
213+
public function getPerformanceMetrics(): array
214+
{
215+
return $this->metrics;
216+
}
174217
}

src/MissingStrings/FileDiscovery/FileDiscovery.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ class FileDiscovery
4343
*/
4444
private $plugin;
4545

46+
/**
47+
* Performance metrics.
48+
*
49+
* @var array{discovery_time: float, directories_scanned: int, files_processed: int}
50+
*/
51+
private $metrics = [
52+
'discovery_time' => 0.0,
53+
'directories_scanned' => 0,
54+
'files_processed' => 0,
55+
];
56+
4657
public function __construct(Plugin $plugin)
4758
{
4859
$this->plugin = $plugin;
@@ -66,6 +77,8 @@ private function ensureDiscovered(): void
6677
*/
6778
private function discoverFiles(): void
6879
{
80+
$startTime = microtime(true);
81+
6982
$this->files = [
7083
'php' => [],
7184
'mustache' => [],
@@ -77,6 +90,8 @@ private function discoverFiles(): void
7790
];
7891

7992
$this->scanDirectory($this->plugin->directory);
93+
94+
$this->metrics['discovery_time'] = microtime(true) - $startTime;
8095
}
8196

8297
/**
@@ -91,6 +106,7 @@ private function scanDirectory(string $directory, string $relativePath = ''): vo
91106
return;
92107
}
93108

109+
++$this->metrics['directories_scanned'];
94110
$iterator = new \DirectoryIterator($directory);
95111

96112
foreach ($iterator as $item) {
@@ -104,6 +120,7 @@ private function scanDirectory(string $directory, string $relativePath = ''): vo
104120
if ($item->isDir()) {
105121
$this->scanDirectory($itemPath, $itemRelativePath);
106122
} elseif ($item->isFile()) {
123+
++$this->metrics['files_processed'];
107124
$this->categorizeFile($itemPath, $itemRelativePath);
108125
}
109126
}
@@ -323,4 +340,18 @@ public function getStatistics(): array
323340
'amd_files' => count($this->files['amd']),
324341
];
325342
}
343+
344+
/**
345+
* Get performance metrics.
346+
*
347+
* @return array performance metrics including timing and file counts
348+
*/
349+
public function getPerformanceMetrics(): array
350+
{
351+
$this->ensureDiscovered();
352+
353+
return array_merge($this->metrics, [
354+
'file_types' => $this->getStatistics(),
355+
]);
356+
}
326357
}

src/MissingStrings/StringValidator.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,14 @@ public function __construct(
147147
*/
148148
public function validate(): ValidationResult
149149
{
150+
$startTime = microtime(true);
151+
150152
$result = new ValidationResult($this->config->isStrict());
151153
$this->errorHandler = new ErrorHandler($result, $this->config->isDebugEnabled());
152154

155+
// Count main plugin
156+
$result->incrementPluginCount();
157+
153158
// Validate the main plugin
154159
$this->validateSinglePlugin($this->plugin);
155160

@@ -159,6 +164,12 @@ public function validate(): ValidationResult
159164
'Validating subplugins'
160165
);
161166

167+
// Record total processing time if debug enabled
168+
if ($this->config->isDebugEnabled()) {
169+
$totalTime = microtime(true) - $startTime;
170+
$result->setProcessingTime($totalTime);
171+
}
172+
162173
return $result;
163174
}
164175

@@ -181,11 +192,24 @@ private function validateSinglePlugin(Plugin $plugin): void
181192
$this->extractor = new StringExtractor();
182193
$this->extractor->setFileDiscovery($this->fileDiscovery);
183194

195+
// Track debug information if enabled
196+
if ($this->config->isDebugEnabled()) {
197+
// Collect file discovery metrics
198+
$fileMetrics = $this->fileDiscovery->getPerformanceMetrics();
199+
$this->errorHandler->getResult()->addFileCounts($fileMetrics['file_types']);
200+
$this->errorHandler->getResult()->addPhaseTime('file_discovery_' . $plugin->component, $fileMetrics['discovery_time']);
201+
}
202+
184203
// Get defined strings from language file
204+
$phaseStart = microtime(true);
185205
$definedStrings = $this->errorHandler->safeExecute(
186206
fn () => $this->getDefinedStrings(),
187207
"Loading language file for {$plugin->component}"
188208
);
209+
if ($this->config->isDebugEnabled()) {
210+
$this->errorHandler->getResult()->addPhaseTime('lang_loading_' . $plugin->component, microtime(true) - $phaseStart);
211+
$this->errorHandler->getResult()->addStringCounts(['defined_strings' => count($definedStrings)]);
212+
}
189213

190214
// Basic validation - check if language file exists
191215
if (empty($definedStrings)) {
@@ -203,37 +227,66 @@ private function validateSinglePlugin(Plugin $plugin): void
203227
}
204228

205229
// Get plugin-specific requirements
230+
$phaseStart = microtime(true);
206231
$requirements = $this->errorHandler->safeExecute(
207232
fn () => $this->requirementsResolver->resolve($plugin, $this->moodle->getBranch()),
208233
"Resolving plugin requirements for {$plugin->component}"
209234
);
235+
if ($this->config->isDebugEnabled()) {
236+
$this->errorHandler->getResult()->addPhaseTime('requirements_resolve_' . $plugin->component, microtime(true) - $phaseStart);
237+
}
210238

211239
if ($requirements) {
212240
// Validate required strings from requirements based on the plugin type.
241+
$phaseStart = microtime(true);
213242
$this->errorHandler->safeExecute(
214243
fn () => $this->validateRequiredStrings($requirements->getRequiredStrings(), $definedStrings),
215244
"Validating required strings for {$plugin->component}"
216245
);
246+
if ($this->config->isDebugEnabled()) {
247+
$this->errorHandler->getResult()->addPhaseTime('required_validation_' . $plugin->component, microtime(true) - $phaseStart);
248+
$this->errorHandler->getResult()->addStringCounts(['required_strings' => count($requirements->getRequiredStrings())]);
249+
}
217250
}
218251

219252
// Run string checkers for database files and other sources.
253+
$phaseStart = microtime(true);
220254
$this->errorHandler->safeExecute(
221255
fn () => $this->runStringCheckers($definedStrings),
222256
"Running string checkers for {$plugin->component}"
223257
);
258+
if ($this->config->isDebugEnabled()) {
259+
$this->errorHandler->getResult()->addPhaseTime('checkers_' . $plugin->component, microtime(true) - $phaseStart);
260+
}
224261

225262
// Find and validate used strings in the plugin code.
263+
$phaseStart = microtime(true);
226264
$this->errorHandler->safeExecute(
227265
fn () => $this->validateUsedStrings($definedStrings),
228266
"Validating used strings for {$plugin->component}"
229267
);
268+
if ($this->config->isDebugEnabled()) {
269+
$this->errorHandler->getResult()->addPhaseTime('used_validation_' . $plugin->component, microtime(true) - $phaseStart);
270+
271+
// Collect string extraction metrics
272+
$extractorMetrics = $this->extractor->getPerformanceMetrics();
273+
$this->errorHandler->getResult()->addStringCounts([
274+
'strings_extracted' => $extractorMetrics['strings_extracted'],
275+
'string_usages_found' => $extractorMetrics['string_usages_found'],
276+
]);
277+
$this->errorHandler->getResult()->addPhaseTime('string_extraction_' . $plugin->component, $extractorMetrics['extraction_time']);
278+
}
230279

231280
// Check for unused strings if requested.
232281
if ($this->config->shouldCheckUnused()) {
282+
$phaseStart = microtime(true);
233283
$this->errorHandler->safeExecute(
234284
fn () => $this->validateUnusedStrings($definedStrings, $requirements),
235285
"Checking for unused strings in {$plugin->component}"
236286
);
287+
if ($this->config->isDebugEnabled()) {
288+
$this->errorHandler->getResult()->addPhaseTime('unused_validation_' . $plugin->component, microtime(true) - $phaseStart);
289+
}
237290
}
238291
} finally {
239292
// Restore original plugin and file discovery
@@ -255,6 +308,9 @@ private function validateSubplugins(): void
255308
}
256309

257310
foreach ($subplugins as $subplugin) {
311+
// Count each subplugin
312+
$this->errorHandler->getResult()->incrementSubpluginCount();
313+
258314
$this->errorHandler->safeExecute(
259315
fn () => $this->validateSinglePlugin($subplugin),
260316
"Validating subplugin {$subplugin->component}",

0 commit comments

Comments
 (0)