HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Benchmarking our LAMP servers with this php script

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisscriptserverswithphplampbenchmarkingour

Problem

I've written a small script to benchmark our LAMP hosted servers that assess the performance based on three factors:

  • Disk I/O



  • Database I/O (mysql)



  • Database I/O (sqlite)



The logic is as follows:

  • get the type of test performed using a querystring value.



  • generate a big random string of 100KB.



  • If (disk-i/o)



write this line to a random file 500 times.

  • else if (mysql i/o)



insert this as record in a mysql table 500 times.

  • else if (sqlite i/o)



insert this as record in a sqlite table 500 times.

  • Write back to response all variables such as the big string ($payload), time taken to write ($wtime), etc..



The program is working fine, but the database i/o is taking way more time than the file i/o. In one test instance, file i/o took only 1.5 seconds, whilst db i/o took 43 seconds! Can you help me with streamlining this code?

```
exec('create table temp(t text)');
$db->exec("begin");
$stmt = $db->prepare("insert into temp values(:id)");
for($i=0;$ibindValue(':id', $payload, SQLITE3_TEXT);
$stmt->execute();
//$db->exec("delete from temp");
};
$db->exec("commit");

}
else if ($type=='mysql') //mysql test
{
$mysqli = new mysqli($mysqlserver, $mysqlusername, $mysqlpassword, $mysqldatabase);
$mysqli->query('create table temp(t varchar(108000))');
$mysqli->query('begin transaction');
for($i=0;$iquery("insert into temp values('{$payload}')");
$mysqli->query('commit');
}
else // Disk I/O
{
$fname = chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).'.txt';
for($i=0;$iquery("select t from temp limit 1");
$result = $result->fetchArray()['t'];
//$db->exec("delete from temp");
};
//var_dump($result);
}
else if ($type=='mysql'){
$stmt = $mysqli->prepare('select t from temp limit 1');
if ($stmt)
{
for($i=0;$iexecute();
$stmt->bind_re

Solution

I'm not to good at optimizing, so I don't think I'm qualified to touch on that aspect.
So, formatting I guess,

One thing I can say though, is that your code is seriously lacking consistency. Some assignments ($mysqlserver = 'localhost';) you place spaces around operators and use single quotes, on some ($payload="";) it's the exact opposite! I suggest you choose a style, or a beautifier for that matter, and apply it to the whole script. It makes reading it, a lot easier. Also, please fix your indentation. Knowing which functions and clauses your closing brackets end is pretty important.
Now the code,

Why $_REQUEST? Are you expecting to receive input from the URL, other pages, and cookies? If so, you may skip this. If not, I suggest you choose between $_GET or $_POST to keep things specific.

How about this:

$n=rand(0,57)+65;
$payload = $payload.chr($n);


It really could be reduced to:

$c = rand(65, 122);
$payload .= chr($c);


I felt a "c" would be better than an "n", but really, variables should have some sort of context in them. So "$charCode" would be excellent. Hold off on fixing this though!

Now I don't feel qualified to critique the actual I/O code, so I'll leave that up to someone with more knowledge. From what I do know though, I can't see any glaring problems with your database queries that would cause it to be so slow. Hopefully some one with an eye keener than mine can help.

Now this:

$fname = chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).'.txt'


is very wet. What I mean by that is, we need to DRY it out a bit!

Head back up to the top, and let's make a nifty function:

function rand_char_str($length) {
    $returnString = "";
    for ($i = 0; $i < $length; $i++) {
        $returnString .= chr(rand(65, 122));
    }
    return $returnString;
}


Great! Now we can replace

for($i=0;$i<108000;$i++) //generate a big string
{
    $n=rand(0,57)+65;
    $payload = $payload.chr($n);
}


with

$payload = rand_char_str(108000);


We can also replace that $fname assignment with

$fname = rand_char_str(4) . ".txt";


Towards the end there, you have

$stmt = $mysqli->prepare('select t from temp limit 1');


and then a conditions checking the value of $stmt. You can just place the method call inside the conditional. This one's just nit-picking though!

Code Snippets

$n=rand(0,57)+65;
$payload = $payload.chr($n);
$c = rand(65, 122);
$payload .= chr($c);
$fname = chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).'.txt'
function rand_char_str($length) {
    $returnString = "";
    for ($i = 0; $i < $length; $i++) {
        $returnString .= chr(rand(65, 122));
    }
    return $returnString;
}
for($i=0;$i<108000;$i++) //generate a big string
{
    $n=rand(0,57)+65;
    $payload = $payload.chr($n);
}

Context

StackExchange Code Review Q#54139, answer score: 5

Revisions (0)

No revisions yet.