1

I am looking for help here to understand whether my code is right approach or not. Because I can't see much improvement in response time. I used guzzle promise to reduce my overall performance.

Existing code :

protected function sampleFunction(&$outputArray){
        foreach($outputArray as $key => $images){
            foreach($images as $index => $image){
              $result = NewClass::ClassSampleFunction($image->path, $this->samplePoint); // This is expensive function calls in current code. 
              }
        }
    }

New code using guzzle promise callback :


protected function sampleFunction(&$outputArray){
        
        foreach($outputArray as $key => $images){
            $promises = array();
            foreach($images as $index => $image){
                $promises[$index] = $this->promiseFunction($image,$index); 
            }

            $results = \GuzzleHttp\Promise\settle($promises)->wait(); 
            foreach ($results as $resultkey => $value) { 
                    $search_point_image_xy_array = $value['value']->toArray();
                    // some logic to use result and put in another response array.
            } 
          } 
    }

protected function promiseFunction($image,$index){
      $promise =  new Promise(
                        function () use ($image,$index,&$promise) {
                            $response = NewClass::ClassSampleFunction($image->path, $this->samplePoint);
                            $promise->resolve($response);
                        },
                        function () {
                            // do something that will cancel the promise computation (e.g., close
                            // a socket, cancel a database query, etc...)
                        }
                    );
        return $promise;
    }

This new code trying to call NewClass::ClassSampleFunction($image->path, $this->samplePoint); this expensive function call using guzzle promise without external endpoint. But after this also expected some reduction in response time but not changes whereas sometime its more than old code.

Mention function call NewClass::ClassSampleFunction($image->path, $this->samplePoint); this run suppose I have first for loop 4 range and second has 10 per first for loop then total 40 times calls goes to this function. If I used async call then First call goes without it finish second goes and vice versa. This can help to use waiting time in old code

What I am doing wrongly ? Any help or recommendation ?

Avinash Dalvi
  • 8,551
  • 7
  • 27
  • 53
  • Which changes are you looking for? Downloading stuff from an external server still takes time. You could try to debug this using blackfire.io – Nico Haase Nov 27 '20 at 07:26
  • This is local function. Nested in multiple local function there is external call. I can't change that external call. Want to use local function as promise to async call. – Avinash Dalvi Nov 27 '20 at 07:44
  • My expectation should if It old code is taking time to finish 5 sec. After using promise async call it should reduce to 500 or 600 ms because no calls should wait for first call to finish. – Avinash Dalvi Nov 27 '20 at 07:52
  • And which calls are still waiting? What have you tried to check for any difference, besides monitoring the time between request start and finish? As these "expensive calls" still have to happen anytime in your application (this means: the execution takes time, regardless of when this happens), I don't think that your are monitoring them properly – Nico Haase Nov 27 '20 at 08:05
  • Mention function call `NewClass::ClassSampleFunction($image->path, $this->samplePoint);` this run suppose I have first for loop 4 range and second has 10 per first for loop then total 40 times calls goest to this function. If I used asyc call then First call goes without it finish second goes and vice versa. This can help to use waiting time in old code. – Avinash Dalvi Nov 27 '20 at 08:08
  • And what have you tried to debug why the performance is not better in the end? Why not run a profiler like blackfire.io to check for differences? – Nico Haase Nov 27 '20 at 08:28
  • I created profile using xdebug not seeing improvement. Even in browser console not seeing response time improvement. – Avinash Dalvi Nov 27 '20 at 09:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/225197/discussion-between-aviboy2006-and-nico-haase). – Avinash Dalvi Nov 27 '20 at 10:15

1 Answers1

0

Finally I able to improve performance by some level by using eachPromise from guzzle/promise.

Revise code :

protected function sampleFunction(&$outputArray){
        
        foreach($outputArray as $key => $images){
            $promises = array();
            foreach($images as $index => $image){
                $promises[$index] = $this->promiseFunction($image,$index); 
            }

           $eachPromise = new EachPromise($promises, [
          // how many concurrency we are use
          'concurrency' => count($promises),
          'fulfilled' => function ($response,$index) use (&$images, &$outputArray)
           {
             //logic for other operation.
               
            },
          'rejected' => function ($reason) {
          }
        ]);
          } 
    }

protected function promiseFunction($image,$index){
      $promise =  new Promise(
                        function () use ($image,$index,&$promise) {
                            $response = NewClass::ClassSampleFunction($image->path, $this->samplePoint);
                            $promise->resolve($response);
                        },
                        function () {
                            // do something that will cancel the promise computation (e.g., close
                            // a socket, cancel a database query, etc...)
                        }
                    );
        return $promise;
    }

Reference article : https://medium.com/@ardanirohman/how-to-handle-async-request-concurrency-with-promise-in-guzzle-6-cac10d76220e

Avinash Dalvi
  • 8,551
  • 7
  • 27
  • 53