🐘 ⚡ Performance Optimization with TuskLang & PHP
⚡ Performance Optimization with TuskLang & PHP
Introduction
Performance optimization is the key to scalable, responsive applications. TuskLang and PHP let you implement sophisticated optimization strategies with config-driven profiling, memory management, database optimization, and caching that maximizes application performance.Key Features
- Application profiling and monitoring - Memory optimization and garbage collection - Database query optimization - Caching strategies - Code optimization techniques - Load balancing and scalingExample: Performance Configuration
[performance]
profiling: @go("performance.ConfigureProfiling")
memory: @go("performance.ConfigureMemory")
database: @go("performance.ConfigureDatabase")
caching: @go("performance.ConfigureCaching")
optimization: @go("performance.ConfigureOptimization")
PHP: Performance Profiler
<?phpnamespace App\Performance;
use TuskLang\Config;
use TuskLang\Operators\Env;
use TuskLang\Operators\Metrics;
use TuskLang\Operators\Go;
class PerformanceProfiler
{
private $config;
private $profiles = [];
private $startTime;
private $memoryStart;
public function __construct()
{
$this->config = new Config();
$this->startTime = microtime(true);
$this->memoryStart = memory_get_usage(true);
}
public function startProfile($name)
{
$profile = [
'name' => $name,
'start_time' => microtime(true),
'start_memory' => memory_get_usage(true),
'start_peak' => memory_get_peak_usage(true)
];
$this->profiles[$name] = $profile;
return $name;
}
public function endProfile($name)
{
if (!isset($this->profiles[$name])) {
throw new \Exception("Profile not found: {$name}");
}
$profile = $this->profiles[$name];
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
$endPeak = memory_get_peak_usage(true);
$duration = ($endTime - $profile['start_time']) * 1000; // Convert to milliseconds
$memoryUsed = $endMemory - $profile['start_memory'];
$peakMemory = $endPeak - $profile['start_peak'];
$result = [
'name' => $name,
'duration' => $duration,
'memory_used' => $memoryUsed,
'peak_memory' => $peakMemory,
'timestamp' => date('c')
];
// Record metrics
Metrics::record("profile_duration", $duration, ["profile" => $name]);
Metrics::record("profile_memory", $memoryUsed, ["profile" => $name]);
// Store profile result
$this->storeProfileResult($result);
return $result;
}
public function profileFunction(callable $function, $name = null)
{
$name = $name ?? 'anonymous_function';
$this->startProfile($name);
try {
$result = $function();
$this->endProfile($name);
return $result;
} catch (\Exception $e) {
$this->endProfile($name);
throw $e;
}
}
public function getOverallStats()
{
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
$endPeak = memory_get_peak_usage(true);
return [
'total_duration' => ($endTime - $this->startTime) * 1000,
'total_memory_used' => $endMemory - $this->memoryStart,
'peak_memory' => $endPeak,
'profiles_count' => count($this->profiles)
];
}
private function storeProfileResult($result)
{
$storage = $this->config->get('performance.profiling.storage', 'memory');
switch ($storage) {
case 'database':
$this->storeInDatabase($result);
break;
case 'file':
$this->storeInFile($result);
break;
case 'redis':
$this->storeInRedis($result);
break;
}
}
private function storeInDatabase($result)
{
$pdo = new PDO(Env::get('DB_DSN'));
$stmt = $pdo->prepare("
INSERT INTO performance_profiles (name, duration, memory_used, peak_memory, timestamp)
VALUES (?, ?, ?, ?, ?)
");
$stmt->execute([
$result['name'],
$result['duration'],
$result['memory_used'],
$result['peak_memory'],
$result['timestamp']
]);
}
private function storeInFile($result)
{
$logFile = $this->config->get('performance.profiling.log_file', 'performance.log');
$logEntry = json_encode($result) . "\n";
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
}
private function storeInRedis($result)
{
$redis = new Redis();
$redis->connect(Env::get('REDIS_HOST', 'localhost'));
$key = "profile:{$result['name']}:" . time();
$redis->setex($key, 3600, json_encode($result));
}
}
class QueryProfiler
{
private $config;
private $queries = [];
public function __construct()
{
$this->config = new Config();
}
public function profileQuery($sql, $params = [], $duration = null)
{
$query = [
'sql' => $sql,
'params' => $params,
'duration' => $duration,
'timestamp' => date('c'),
'memory' => memory_get_usage(true)
];
$this->queries[] = $query;
// Record slow queries
$slowThreshold = $this->config->get('performance.database.slow_query_threshold', 100);
if ($duration > $slowThreshold) {
$this->recordSlowQuery($query);
}
return $query;
}
public function getSlowQueries($threshold = null)
{
$threshold = $threshold ?? $this->config->get('performance.database.slow_query_threshold', 100);
return array_filter($this->queries, function($query) use ($threshold) {
return $query['duration'] > $threshold;
});
}
public function getQueryStats()
{
if (empty($this->queries)) {
return [];
}
$durations = array_column($this->queries, 'duration');
return [
'total_queries' => count($this->queries),
'total_duration' => array_sum($durations),
'average_duration' => array_sum($durations) / count($durations),
'min_duration' => min($durations),
'max_duration' => max($durations),
'slow_queries' => count($this->getSlowQueries())
];
}
private function recordSlowQuery($query)
{
$logFile = $this->config->get('performance.database.slow_query_log', 'slow_queries.log');
$logEntry = json_encode($query) . "\n";
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
// Send alert for very slow queries
$criticalThreshold = $this->config->get('performance.database.critical_query_threshold', 1000);
if ($query['duration'] > $criticalThreshold) {
$this->sendSlowQueryAlert($query);
}
}
private function sendSlowQueryAlert($query)
{
$alert = [
'type' => 'slow_query',
'sql' => $query['sql'],
'duration' => $query['duration'],
'timestamp' => $query['timestamp']
];
// Send to monitoring system
Metrics::record("critical_slow_query", 1, [
"duration" => $query['duration'],
"sql" => substr($query['sql'], 0, 100)
]);
}
}
Memory Optimization
<?phpnamespace App\Performance\Memory;
use TuskLang\Config;
class MemoryManager
{
private $config;
private $monitor;
public function __construct()
{
$this->config = new Config();
$this->monitor = new MemoryMonitor();
}
public function optimizeMemory()
{
$this->monitor->start();
// Clear unnecessary variables
$this->clearUnusedVariables();
// Optimize arrays
$this->optimizeArrays();
// Force garbage collection
$this->forceGarbageCollection();
$this->monitor->end();
}
public function getMemoryUsage()
{
return [
'current' => memory_get_usage(true),
'peak' => memory_get_peak_usage(true),
'limit' => ini_get('memory_limit'),
'usage_percentage' => $this->getUsagePercentage()
];
}
public function isMemoryLow()
{
$usage = $this->getMemoryUsage();
$threshold = $this->config->get('performance.memory.low_threshold', 80);
return $usage['usage_percentage'] > $threshold;
}
private function clearUnusedVariables()
{
// Clear global variables that are no longer needed
if (isset($GLOBALS['unused_var'])) {
unset($GLOBALS['unused_var']);
}
// Clear session variables if not needed
if (isset($_SESSION['temp_data'])) {
unset($_SESSION['temp_data']);
}
}
private function optimizeArrays()
{
// Convert associative arrays to indexed arrays where possible
// Use SplFixedArray for large numeric arrays
}
private function forceGarbageCollection()
{
if (function_exists('gc_collect_cycles')) {
gc_collect_cycles();
}
}
private function getUsagePercentage()
{
$current = memory_get_usage(true);
$limit = $this->parseMemoryLimit(ini_get('memory_limit'));
if ($limit === -1) {
return 0; // No limit
}
return ($current / $limit) * 100;
}
private function parseMemoryLimit($limit)
{
$value = (int) $limit;
$unit = strtolower(substr($limit, -1));
switch ($unit) {
case 'k':
return $value * 1024;
case 'm':
return $value 1024 1024;
case 'g':
return $value 1024 1024 * 1024;
default:
return $value;
}
}
}
class MemoryMonitor
{
private $startMemory;
private $startPeak;
public function start()
{
$this->startMemory = memory_get_usage(true);
$this->startPeak = memory_get_peak_usage(true);
}
public function end()
{
$endMemory = memory_get_usage(true);
$endPeak = memory_get_peak_usage(true);
$memoryUsed = $endMemory - $this->startMemory;
$peakUsed = $endPeak - $this->startPeak;
// Record metrics
Metrics::record("memory_optimization_saved", $memoryUsed);
Metrics::record("peak_memory_reduction", $peakUsed);
return [
'memory_saved' => $memoryUsed,
'peak_reduction' => $peakUsed
];
}
}
Database Optimization
<?phpnamespace App\Performance\Database;
use TuskLang\Config;
class DatabaseOptimizer
{
private $config;
private $pdo;
private $profiler;
public function __construct()
{
$this->config = new Config();
$this->pdo = new PDO(Env::get('DB_DSN'));
$this->profiler = new QueryProfiler();
}
public function optimizeQueries()
{
$queries = $this->getSlowQueries();
foreach ($queries as $query) {
$optimized = $this->optimizeQuery($query);
$this->applyOptimization($optimized);
}
}
public function analyzeQuery($sql)
{
$stmt = $this->pdo->prepare("EXPLAIN {$sql}");
$stmt->execute();
return $stmt->fetchAll();
}
public function suggestIndexes()
{
$suggestions = [];
// Analyze slow queries for missing indexes
$slowQueries = $this->profiler->getSlowQueries();
foreach ($slowQueries as $query) {
$analysis = $this->analyzeQuery($query['sql']);
$indexSuggestions = $this->generateIndexSuggestions($analysis);
if (!empty($indexSuggestions)) {
$suggestions[] = [
'query' => $query['sql'],
'suggestions' => $indexSuggestions
];
}
}
return $suggestions;
}
public function optimizeTable($tableName)
{
// Analyze table
$this->pdo->exec("ANALYZE TABLE {$tableName}");
// Optimize table
$this->pdo->exec("OPTIMIZE TABLE {$tableName}");
// Update table statistics
$this->updateTableStats($tableName);
}
private function optimizeQuery($query)
{
$sql = $query['sql'];
// Remove unnecessary SELECT *
$sql = preg_replace('/SELECT \*/', 'SELECT specific_columns', $sql);
// Add LIMIT where missing
if (!preg_match('/LIMIT \d+/i', $sql)) {
$sql .= ' LIMIT 1000';
}
// Use indexes
$sql = $this->addIndexHints($sql);
return [
'original' => $query['sql'],
'optimized' => $sql,
'improvements' => $this->calculateImprovements($query['sql'], $sql)
];
}
private function addIndexHints($sql)
{
// Add FORCE INDEX hints for known slow queries
$indexHints = $this->config->get('performance.database.index_hints', []);
foreach ($indexHints as $pattern => $index) {
if (preg_match($pattern, $sql)) {
$sql = str_replace('FROM ', "FROM {$index} ", $sql);
}
}
return $sql;
}
private function generateIndexSuggestions($analysis)
{
$suggestions = [];
foreach ($analysis as $row) {
if ($row['type'] === 'ALL') {
// Full table scan detected
$suggestions[] = "Add index on {$row['table']} for columns used in WHERE clause";
}
}
return $suggestions;
}
private function updateTableStats($tableName)
{
$stmt = $this->pdo->prepare("
SELECT
table_rows,
data_length,
index_length
FROM information_schema.tables
WHERE table_name = ?
");
$stmt->execute([$tableName]);
$stats = $stmt->fetch();
// Store table statistics
Metrics::record("table_stats", 1, [
"table" => $tableName,
"rows" => $stats['table_rows'],
"data_size" => $stats['data_length'],
"index_size" => $stats['index_length']
]);
}
}
Caching Optimization
<?phpnamespace App\Performance\Caching;
use TuskLang\Config;
class CacheOptimizer
{
private $config;
private $cache;
public function __construct()
{
$this->config = new Config();
$this->cache = new MultiLevelCache();
}
public function optimizeCache()
{
// Analyze cache hit rates
$hitRates = $this->analyzeHitRates();
// Optimize TTLs based on access patterns
$this->optimizeTTLs($hitRates);
// Preload frequently accessed data
$this->preloadFrequentData();
// Clean up expired entries
$this->cleanupExpiredEntries();
}
public function analyzeHitRates()
{
$stats = $this->cache->getStats();
$hitRates = [];
foreach ($stats as $cacheLevel => $stat) {
$hitRates[$cacheLevel] = $stat['hit_rate'];
}
return $hitRates;
}
public function optimizeTTLs($hitRates)
{
$optimizations = $this->config->get('performance.caching.ttl_optimizations', []);
foreach ($optimizations as $pattern => $optimization) {
if ($hitRates['l1'] < $optimization['min_hit_rate']) {
// Increase TTL for better hit rates
$newTTL = $optimization['current_ttl'] * $optimization['multiplier'];
$this->updateTTL($pattern, $newTTL);
}
}
}
public function preloadFrequentData()
{
$frequentData = $this->getFrequentAccessPatterns();
foreach ($frequentData as $pattern) {
$data = $this->loadDataForPattern($pattern);
$this->cache->set($pattern['key'], $data, $pattern['ttl']);
}
}
public function cleanupExpiredEntries()
{
$this->cache->cleanup();
// Record cleanup metrics
Metrics::record("cache_cleanup", 1);
}
private function getFrequentAccessPatterns()
{
// Analyze access logs to find frequently accessed data
$accessLogs = $this->loadAccessLogs();
$patterns = [];
foreach ($accessLogs as $log) {
$key = $log['cache_key'];
if (!isset($patterns[$key])) {
$patterns[$key] = 0;
}
$patterns[$key]++;
}
// Return top accessed patterns
arsort($patterns);
return array_slice($patterns, 0, 10, true);
}
private function loadAccessLogs()
{
// Load cache access logs from storage
$logFile = $this->config->get('performance.caching.access_log', 'cache_access.log');
if (!file_exists($logFile)) {
return [];
}
$logs = [];
$handle = fopen($logFile, 'r');
while (($line = fgets($handle)) !== false) {
$logs[] = json_decode($line, true);
}
fclose($handle);
return $logs;
}
}
Code Optimization
<?phpnamespace App\Performance\Code;
use TuskLang\Config;
class CodeOptimizer
{
private $config;
public function __construct()
{
$this->config = new Config();
}
public function optimizeCode($code)
{
// Remove unnecessary whitespace
$code = $this->removeUnnecessaryWhitespace($code);
// Optimize string concatenation
$code = $this->optimizeStringConcatenation($code);
// Optimize loops
$code = $this->optimizeLoops($code);
// Optimize function calls
$code = $this->optimizeFunctionCalls($code);
return $code;
}
public function generateOptimizedCode($template, $data)
{
// Use efficient string interpolation
$code = $this->interpolateStrings($template, $data);
// Minimize object creation
$code = $this->minimizeObjectCreation($code);
return $code;
}
private function removeUnnecessaryWhitespace($code)
{
// Remove extra spaces and newlines
$code = preg_replace('/\s+/', ' ', $code);
$code = trim($code);
return $code;
}
private function optimizeStringConcatenation($code)
{
// Replace string concatenation with interpolation where possible
$code = preg_replace('/\$(\w+)\s\.\s\$(\w+)/', '${$1}{$2}', $code);
return $code;
}
private function optimizeLoops($code)
{
// Use foreach instead of for where possible
$code = preg_replace('/for\s\(\$i\s=\s0;\s\$i\s<\scount\s\(\$(\w+)\);\s\$i\+\+\)/', 'foreach ($$1 as $item)', $code);
return $code;
}
private function optimizeFunctionCalls($code)
{
// Cache function results where possible
$code = preg_replace('/\$(\w+)\s=\s(\w+)\(\);\sif\s\(\$\1\)/', 'if (($1 = $2()))', $code);
return $code;
}
private function interpolateStrings($template, $data)
{
// Use efficient string interpolation
$placeholders = array_map(function($key) {
return "{{$key}}";
}, array_keys($data));
return str_replace($placeholders, array_values($data), $template);
}
private function minimizeObjectCreation($code)
{
// Reuse objects where possible
$code = preg_replace('/new\s+(\w+)\s\(\s\);\s\$(\w+)\s=\snew\s+\1\s\(\s*\)/', '$2 = new $1()', $code);
return $code;
}
}