views:

174

answers:

4

The $res contains around 488k rows the whole loop takes 61s! that's over 1.25ms per cycle! What is taking all that time?

while($row = $res->fetch_assoc())
{
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['std'] = $row['cost_std'];
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['ecn'] = $row['cost_ecn'];
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['wnd'] = $row['cost_wnd'];
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['other_destination'] = $row['destination_id'];
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['carrier_destination'] = $row['carrier_destination_id'];
}

Now resultset of 10 rows, smaller arrays and performance 30 times higher (0.041ms) not the fastest still but better.

while($row = $res->fetch_assoc())
{
    $customer[$row['id']]['name'] = $row['name'];
    $customer[$row['id']]['code'] = $row['customer'];
}
+2  A: 

Big arrays take more time to allocate memory and handle. that's why we always ask a database to do all the job and return 10 rows as a final result.

Col. Shrapnel
I thought that was just because we were **lazy**
Matthew Scharley
Thanks. No way to speed it up? It's not a web app but a small php deamon messing with a lot of data. So I don't mind to wait but a minute at 100% cpu is a bit extreme and the resultset will grow by a factor of 10 minimum.
pawpro
Do whatever you can in the database. It will *always* be faster than code you write. And you get the added bonus of less code you need to write.
Matthew Scharley
Can you break the data up and do it in smaller work units?
Richard
I.E. from what you said one could extrapolate that the way to get the desired 30 times boost would be to just break the array down to smaller ones...
pawpro
@pawpro from what we have said, you have to use a database to do the calculations on this data
Col. Shrapnel
A: 

I suspect that what's taking all the time is the continual access to 4-dimensional arrays, where some (or all?) of the dimensions are being keyed from string fields, those values themselves having to be extracted from $row...

I would suggest you seriously reconsider:

  1. whether you need all that in memory
  2. if so, what the best data structure would be for optimal access
Alnitak
+1  A: 
Chris Smith
Thanks. I do actually need random data from the database at high rates so I hoped not to have to put strain on the db as I might have continous bursts of data to process at rates higher than 500 q/s and I cannot currently afford to have such unpredictible load on the db. I'll play with it more worst case I'll try memcached :)
pawpro
A: 

What about this:

$cache = array();
while($row = $res->fetch_assoc())
{
    $key = $row['upload_id']."\n".$row['dialcode_id']."\n".$row['carrier_id'];
    $key1 = "1\n$key";
    if (!array_key_exists($key1, $cache))
      $cache[$key1] = &$clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']];

    $ref = &$cache[$key1];
    $ref['std'] = $row['cost_std'];
    $ref['ecn'] = $row['cost_ecn'];
    $ref['wnd'] = $row['cost_wnd'];

    $key2 = "2\n$key";
    if (!array_key_exists($key2, $cache))
      $cache[$key2] = &$dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]

    $ref = &$cache[$key2];
    $ref['other_destination']   = $row['destination_id'];
    $ref['carrier_destination'] = $row['carrier_destination_id'];
}
Tomalak
I see where you going with this...nice I'll give memcached a shot first :)
pawpro
@pawpro: memcached will not speed up the act of indexing into an array itself. Since you do many equal lookups in a loop, even a memcached-based solution would benefit from this approach.
Tomalak
I do relize but I expect only <1% of this data to be in regular use rest will be "on demand from DB". So it is reasonable to cache it using memcached (db query cache would result in high cache miss rate as the table changes - but not the existing data)
pawpro