[drupal-devel] Re: More profiling code - the server this time
Hi Robert, Robert Douglass <rob@robshouse.net> wrote:
I'd be pretty interested in seeing this code and would love to help you port it to Drupal. If you don't want to wait for CVS access we could put it in my sandbox.
It's not a lot of code so I've just pasted it in here. No problems with you putting it up in your sandbox. I'm still new to drupal so hints on locations for a temp directory where this could be written, the cache table is probably be used. Also, is there is an existing script timer tool built in. I can send along the class that this script uses if there isn't one built in. Also, the values I put in for the base number of cycles were designed so that they would take about a second on an old machine. A shorter number of cycles made it harder to judge the relative speed and more cycles caused the problems on really slow servers. /* Do some really simple math a bunch of times */ function profileProcessorSpeed($max = 1000) { // for ($i=0 ; $i < $max ; ++$i) { $bigArray[] = 3 * $i; } foreach($bigArray AS $bigItem) { $value = $bigItem / 2; } // echo "$value end"; } /* Read/Write a bunch of files to a temp directory */ function profileDiskSpeed($max = 400) { global $_PSL, $scriptTimer; $contents = $handle = null; $dir = $_PSL['basedir'] . '/updir/fileCache/'; $scriptTimer->start('diskSpeed'); for ($i=0 ; $i < $max ; ++$i) { if ($scriptTimer->get_current('diskSpeed') > 30) { echo "Script Interrupted, $i disk cycles completed"; return $i; break; } $filename = $dir . 'testFile_' . $i . '.txt'; $somecontent = "Add this to the file $i \n"; // Let's make sure the directory is writable first. if (is_writable($dir)) { // Open file if (!$handle = fopen($filename, 'a')) { echo "Cannot open file ($filename)"; exit; } // Write $somecontent to our opened file. if (fwrite($handle, $somecontent) === FALSE) { echo "Cannot write to file ($filename)"; exit; } fclose($handle); // Read contents $handle = fopen($filename, 'r'); $contents .= fread($handle, filesize($filename)); fclose($handle); unlink($filename); } else { echo "The directory $dir is not writable"; } } return null; } /* Insert/Update/Delete a bunch of files into a cache table */ function profileDBaccess($max = 400) { global $_PSL, $scriptTimer; $contents = null; $db = pslNew('BEDB'); $scriptTimer->start('dbSpeed'); for ($i=0 ; $i < $max ; ++$i) { if ($scriptTimer->get_current('dbSpeed') > 30) { echo "Script Interrupted, $i database cycles completed"; return $i; break; } $j = $i + 30000; $query = "SELECT value FROM psl_variable WHERE variable_id = '$j'"; $db->query($query); while ($db->next_record()) { if ($db->Record['value']) { $query = "DELETE FROM psl_variable WHERE variable_id = '$j'"; $db->query($query); } } $query = "INSERT INTO psl_variable (variable_id, value, variable_name) VALUES ('$j', 'Inserted Value $j', 'Test$j')"; $db->query($query); $query = "UPDATE psl_variable SET value = 'Updated Value $j' WHERE variable_id = '$j'"; $db->query($query); $query = "SELECT value FROM psl_variable WHERE variable_id = '$j'"; $db->query($query); if ($db->next_record()) { $contents .= $db->Record['value']; } $query = "DELETE FROM psl_variable WHERE variable_id = '$j'"; $db->query($query); } return null; } // Start log content $content = '<p>' . date("D M j G:i:s T Y") . ' - '; $scriptTimer->start('profile'); $processorCycles = 10000; profileProcessorSpeed($processorCycles); $processorSpeed = $scriptTimer->get_current('profile'); $content .= "Processor Speed ($processorCycles Cycles): $processorSpeed - "; $fileCycles = 400; $diskCycleResults = profileDiskSpeed($fileCycles); $diskCycleResults = (!empty($diskCycleResults)) ? $diskCycleResults : $fileCycles; $diskSpeed = $scriptTimer->get_current('profile') - $processorSpeed; $content .= "Disk Speed ($diskCycleResults Cycles): $diskSpeed - "; $dbCycles = 250; $dbCycleResults = profileDBaccess($dbCycles); $dbCycleResults = (!empty($dbCycleResults)) ? $dbCycleResults : $dbCycles; $dbSpeed = $scriptTimer->get_current('profile') - $processorSpeed - $diskSpeed; $content .= "DB Speed ($dbCycleResults Cycles): $dbSpeed </p>\n"; $dir = $_PSL['basedir'] . '/updir/fileCache'; $filenameLog = $dir . '/profileLog.txt'; $filenameAverage = $dir . '/profileAverage.txt'; // Read contents of log if (is_readable($filenameLog)) { $handle = fopen($filenameLog, 'r'); $contents .= fread($handle, filesize($filenameLog)); fclose($handle); } // Write log if (!$handle = fopen($filenameLog, 'a')) { echo "Cannot open file ($filenameLog)"; exit; } if (fwrite($handle, $content) === FALSE) { echo "Cannot write to file ($filenameLog)"; exit; } fclose($handle); // Read contents of log if (is_readable($filenameAverage)) { $handle = fopen($filenameAverage, 'r'); $values = unserialize(fread($handle, filesize ($filenameAverage))); fclose($handle); $count = $values['count'] + 1; $processor = (($values['processor'] * $values['count']) + $processorSpeed) / $count; $disk = (($values['disk'] * $values['count']) + $diskSpeed) / $count; $database = (($values['database'] * $values['count']) + $dbSpeed) / $count; } else { $count = 1; $processor = $processorSpeed; $disk = $diskSpeed; $database = $dbSpeed; } $average = "<p>Count $count - Processor Speed (100000 Cycles): $processor - Disk Speed (400 Cycles): $disk - DB Speed (250 Cycles): $database </p>"; // Write log $value = serialize(array('count' => $count, 'processor' => $processor, 'disk' => $disk, 'database' => $database)); if (!$handle = fopen($filenameAverage, 'w')) { echo "Cannot open file ($filenameAverage)"; exit; } if (fwrite($handle, $value) === FALSE) { echo "Cannot write to file ($filenameAverage)"; exit; } fclose($handle); echo "<h1>Last Results</h1> $content <h1>Average Results</h1> $average <h1>All Results</h1> $contents "; Feel free to enhance any of this. Would be neat to see it as a drupal module. Mike -- Mike Gifford, OpenConcept Consulting Free Software for Social Change -> http://www.openconcept.ca Latest launch Canadian Labour Congress / Congrès du travail du Canada http://canadianlabour.ca / http://congresdutravail.ca
http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/robertdouglass/pr... There you go! Because I was too lazy to make up some database tables and fill them with junk data to SELECT/UPDATE/INSERT/DELETE, I used the cache table. This code takes the first record in your cache table, wipes the table clean, inserts the first record 100 times, updates it 100 times deletes it and starts over. In case you didn't read that last paragraph ***this code wipes your cache table clean*** so don't use it if you feel personally attached to its contents. cheers, Robert PS anybody who wants to improve the code can commit directly to my sandbox.
PS here are results from my 1.3GHz Intel Pentium M: Processor Speed (10000 Cycles): 49.43 Disk Speed (166 Cycles): 1006.63 DB Speed (123 Cycles): 10047.65 Because of the way the code is right now the interesting figure for the processor speed is the second number (49.43, lower is better) whereas the interesting number for the other two is the number of cycles (166 and 123, bigger is better). We'll do some work on this to make the numbers easier to make sense of. We also need a way to clear the records - erase the tmp files etc. Actually, the records should be kept as variables, I think: variable_set('profiler_results', $results); Mike, want to update the code? -Robert Robert Douglass wrote:
http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/robertdouglass/pr...
There you go!
Because I was too lazy to make up some database tables and fill them with junk data to SELECT/UPDATE/INSERT/DELETE, I used the cache table. This code takes the first record in your cache table, wipes the table clean, inserts the first record 100 times, updates it 100 times deletes it and starts over.
In case you didn't read that last paragraph ***this code wipes your cache table clean*** so don't use it if you feel personally attached to its contents.
cheers,
Robert
PS anybody who wants to improve the code can commit directly to my sandbox.
participants (2)
-
Mike Gifford -
Robert Douglass