Home » Php » php – How to optimize this array loop

php – How to optimize this array loop

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have array which contains info about many flights. I want only the five lowest prices.

First I make a loop to sort array by price.

Second I print first five array

But it takes more time..How can I reduce this time?

foreach ($flights_result->json_data['response']['itineraries'] as $key => $value)
{
    $mid[$key] = $value['price']['totalAmount'];
}

//Sort the data with mid descending
//Add $data as the last parameter, to sort by the common key
array_multisort($mid, SORT_ASC, $flights_result->json_data['response']['itineraries']);

// print 5 arrays
foreach ($flights_result->json_data['response']['itineraries'] as  $value)
{
    echo 'departureTime:' . $value['inboundInfo']['departureTime'] . '</br>';
    echo 'layoverInMin:' . $value['inboundInfo']['layoverInMin'] . '</br>';
    //      // loop echo 

    foreach ($value['inboundInfo']['flightNumbers'] as $flightNumbers)
    {
        echo 'flightNumbers  :' . $flightNumbers . '</br>';
    }

    echo 'durationInMin:' . $value['inboundInfo']['durationInMin'] . '</br>';
    echo 'localDepartureTimeStr:' . $value['inboundInfo']['localDepartureTimeStr'] . '</br>';
    echo ' arrivalTime:' . $value['inboundInfo']['arrivalTime'] . '</br>';
    echo ' numStops:' . $value['inboundInfo']['numStops'] . '</br>';

    ////     loop 
    foreach ($value[' inboundInfo']['flightClasses'] as $flightClasses)
    {
        echo 'flightClasses name :' . $flightClasses['name'] . '</br>';
        echo 'flightClasses fareClass :' . $flightClasses['fareClass'] . '</br>';
    }

    echo 'localArrivalTimeStr:' . $value['inboundInfo']['localArrivalTimeStr'] . '</br>';
    //      loop  echo

    foreach ($value[' carrier'] as $carrier)
    {
        echo 'carrier name :' . $carrier['name'] . '</br>';
        echo 'carrier code :' . $carrier['code'] . '</br>';
    }

    echo 'amount:' . $value['price']['amount'] . '</br>';
    echo ' totalAmount :' . $value['price']['totalAmount'] . '</br>';
    echo 'pricePerPassenger:' . $value['price']['pricePerPassenger'] . '</br>';
    echo 'currencyCode: ' . $value['price']['currencyCode'] . '</br>';
    echo 'totalPricePerPassenger: ' . $value['price']['totalPricePerPassenger'] . '</br>';
    echo 'includesTax: ' . $value['price ']['includesTax'] . '</br>';
    echo 'destinationCountryCode:' . $value[' destinationCountryCode'] . ' </br> -------- </br>';

    $count++;
    if ($count > 2)
    {
        break;
    }
}

array example

)

How to&Answers:

To answer your questions:

but it take more time..how to reduce this big time?

Before you can reduce that you need to find out exactly where that more comes from. As you wrote in a comment, you are using a remote request to obtain the data.

Sorting for array the data you’ve provided works extremely fast, so I would assume you don’t need to optimize the array sorting but just the way when and how you get the data from remote. One way to do so is to cache that or to prefetch it or to do parallel processing. But the details so far are not important at all, unless you’ve found out where that more comes from so that it is clear what is responsible for big time so then it can be looked into reducing it.

Hope this is helpful so far, and feel free to add the missing information to your question.

You can see the array-only code in action here, it’s really fast:

You can find the execution stats just below the output, exemplary from there:

OK (0.008 sec real, 0.006 sec wall, 14 MB, 99 syscalls)

Answer:

You should really install a profiler (XHProf) and check what exactly takes so much time.

I assume it is the sorting, because foreach through the final array of 5 elements should be lighning fast. Why do you sort it then? If the sole purpose of sorting is to find 5 “lowest” items, then the fastest way would be to just find 5 lowest items:

It will find 5 items with about O(6n) which in your case should better than potential O(n²) with sorting; Then you may just use it like:

This should be a lot faster, provided it was the sorting! so get that XHprof and check 🙂

Answer:

Here’s what I would have done:

It’s either that or write a recursive function to go through all the data. Also note, this only works if your data is in the order you want.

Answer:

I would do the following things:

Answer:

Buffer echo/print (ie, do not echo/print from inside loop):

This is probably negligable in your case, but worth doing for larger iteration counts.

You don’t need to sort the entire array if you’re only interested in the 5 lowest prices.

Loop through the array while maintaining a list of the keys with the 5 lowest prices.

I’m too rusty in PHP to effectively provide a sample.

Answer:

I see two potential areas slowing down the code:

  • Sorting the array
  • Echoing + string concatenating all those strings

I would first find out which area is causing the lag. If profiling is difficult, you can insert debugging print statements into your code with each statement print the current time. This will give you a rough idea, which area of code is taking bulk of the time. Something like:

Once we have those results we can optimize further.

Answer:

Try this…

Answer:

The first thing to understand is which part of you code takes long to execute.
A quick and dirty but simple way is to use your logger.
Which I assume you are using already to log all your other information you want to keep as your code runs,
such as memory usage, disc usage, user requests, purchases made etc.

Your logger can be a highly sofisticated tool (just google for “loggin framework” or the likes)
or as simple as message writer to your file.
To get a quick start, you can using something like that:

Now you can go over your code and place your loggers at all crucial points after
anything that may potentially take too long. Add your messages to know what happened.
There can potentially be many places for delays.
Usually array manipulations done in-memory are blazing fast.
But more attention needs to be paid for more time consuming operations such as:

  • File reading/ writing, directory access
  • Database access
  • HTTP requests

For instance, http requests – are your echos being sent immediately to browser over a network?
Are they being sent every time in the loop?
If yes, you probably want to avoid it.
Either save them into array as indicated by other answers,
or use Output Buffering.

Further to minimize http requests to your server, you can try to put more functions
on the client side and use ajax to only retrieve what is really needed from the server.

Also don’t forget about things that are hidden.
For instance, I see object property access:

How is this object implemented? Is it in-memory only? Does it call to outside services?
If yes, that may be your culprit. Then you have to work on optimizing that.
Reducing the number of queries by caching them, optimizing your data so you only need to query the changes, etc.
All this depends on the structure of you application and may have nothing to do with the rest of your code.
If you want any help on that, you obviously need to put this information in your question.

Basically anything that is not done entirely in memory can cause delays.
As for the in-memory operations, unless your data are huge or your operations are intense,
their effect will likely be negligible.
Still if you have any doubt, simply place your loggers at all “suspicious” places.


Now to your specific code, it mixes all sort of things,
such that outside object access, array value access, array sorting,
echo outputs, maybe other things that are hidden.
This makes it hard even to know where to place your time loggers.

What would make it much easier, is to use object oriented approach
and follow, among others, the Principle of Separating Concerns (google on that).
That way your objects and their methods will have single responsibilities
and you will easily see who does what and where to place your loggers.

I can’t highly enough recommend the legendary book by “Uncle Bob” to learn more about it.
I presume your code comes from inside a function. According to Uncle Bob:

The first rule of functions is that they should be small. The second rule is that they should be smaller than that.

and

Functions should do one thing. They should do it well. They should do it only.

When splitting your code into more functions, you are forced to give those functions meaningful names that can greatly improve readability of your code. Needless to say, all functions not intended for use outside the class, should be private, so you can easily re-use your classes via inheritance.


There is a lot that can be done, but just to get you started, here are some ideas:

  • Encapsulate your data array into an object with methods only doing there what you need. Something like that:

Notice that should your array structure completely change,
you’ll only need to adjust the method _getPrice
and the single line to instantiate your object!
The rest of your code will remain intact!

This is a part of your Model Layer in the Model-View-Controller paradigm.
You can google on that to find lots of information.
The model knows how to handle its data but knows nothing about
the source of them, no browser output, no http requests etc.

  • Then everything responsible for generating user output goes into your View Layer or into so-called Presenter Layer,
    where you have other objects dealing with it. All your ‘echo’s will go here.
    Something like that:


However, I am personally against generating HTML on the server.
It is just a waste of bandwidth and the time of your users waiting for response.
Every time I am waiting for my browser to reload the whole page, I want the developer to read this.
You can output JSON instead of HTML and request it with ajax or via other ways on the client side.

Furthermore, your user’s browser can cache some of the data instead of requesting them again,
and decide what to ask for. That will further minimize the delay for your users,
which at the end of the day is precisely what you are concerned with.