algolia / algoliasearch-client-php

⚡️ A fully-featured and blazing-fast PHP API client to interact with Algolia.
https://www.algolia.com/doc/api-client/php/getting-started/
MIT License
671 stars 116 forks source link

PHP Client performs poorly #165

Closed appkr closed 7 years ago

appkr commented 8 years ago

According to my profiling result, in case of JS client it is reported that the wall-clock time is 3 ms. But with the PHP client it takes 300 ~ 400 ms.

In your Client::doRequest method, 7~50 loop happens while requesting CURL. Any plan to replace CURL to another http client? I'll do my test with Algolia REST API and guzzle today.

The following is the code that I used for profiling. (3 consecutive queris. Don't ask why? That's just the company's requirement.)

<?php

define('ALGOLIA_START', microtime(true));

require __DIR__ . '/./vendor/autoload.php';

$client = new \AlgoliaSearch\Client('***', '***');
$storeIndex = $client->initIndex('stores_tentative');
$productIndex = $client->initIndex('products_tentative');

if (isset($_GET['q'])) {
    $keyword = $_GET['q'];

    $sections[] = $storeIndex->search($keyword, [
        'hitsPerPage' => 20,
        'filters' => 'isCvs=0 AND deliverableRegions=2906'
    ])['hits'];

    $sections[] = $productIndex->search($keyword, [
        'hitsPerPage' => 20,
        'filters' => 'isCvs=0 AND deliverableRegions=2906'
    ])['hits'];

    $sections[] = $productIndex->search($keyword, [
        'hitsPerPage' => 50,
        'filters' => 'isCvs=1 AND deliverableRegions=2906'
    ])['hits'];

    $processingTime = round((microtime(true) - ALGOLIA_START) * 1000); // 300~400 ms
}
<script>
  new Vue({
    el: '#app',

    data: {
      keyword: '',
      processingTime: 0,
      results: {
        cuisine: {
          stores: [],
          products: []
        },
        cvs: {
          stores: [],
          products: []
        }
      }
    },

    mounted: function () {
      var client = algoliasearch('***', '***');
      this.storeIndex = client.initIndex('stores_tentative');
      this.productIndex = client.initIndex('products_tentative');
    },

    methods: {
      search: function () {
        var ALGOLIA_START = performance.now();

        // Cuisine Store
        this.storeIndex.search(this.keyword, {
          filters: 'isCvs=0 AND deliverableRegions=2906',
          hitsPerPage: 20
        }, function (err, content) {
          this.results.cuisine.stores = content.hits;
        }.bind(this));

        // Cuisine Product
        this.productIndex.search(this.keyword, {
          filters: 'isCvs=0 AND deliverableRegions=2906',
          hitsPerPage: 20
        }, function (err, content) {
          this.results.cuisine.products = content.hits;
        }.bind(this));

        // CVS Product
        this.productIndex.search(this.keyword, {
          filters: 'isCvs=1 AND deliverableRegions=2906',
          hitsPerPage: 50
        }, function (err, content) {
          this.results.cvs.products = content.hits;
        }.bind(this));

        this.processingTime = Math.round(performance.now() - ALGOLIA_START); // 3 ms
      }
    }
  });
</script>
maxiloc commented 8 years ago

@appkr Thanks for reporting I don't think you can not compare it that way. At the moment you compute the processing time for js, the query is not finished yet, it's just triggered. That being said 300/400ms for 3 queries seems like a lot and we are experiencing the same kind of time, we going to investigate to see if there is something wrong with the code.

appkr commented 8 years ago

Yes you're right. I made a mistake in JS code :) that is because I am more familiar with synchronous thing. Anyway the CURL code is not beautiful neither performing well.

Last 14 days I used Algolia with free trial plan and It was good in terms of accuracy and conveniences. Sorry to say this, but I had to resort to ES. Even though the api client is very hard to use(almost 10 indentation of array expression for one query param), but it's free and fast(in PHP). Hope to get back to Algolia someday. Thanks.

maxiloc commented 8 years ago

Yes we are going to check what we can do and I hope we'll fix it and have you back as customer. Thanks for the feedback

rayrutjes commented 7 years ago

Hi @appkr ,

After investigation it appears the first request will require approximately 200ms to open the Keep Alived connexion. After that, the response time is of 20ms.

Those results obviously depend on the location of your server and the region of your Algolia data.

Here is the code we used to test it:

<?php
// ...
public function testAverageRequestTime()
    {
        $start = microtime(true);

        $iterations = 20;
        for($i = 0; $i < $iterations; $i++) {
            $this->client->listIndexes();
        }

        $time = round(((microtime(true) - $start) * 1000)/$iterations);

        $this->assertLessThan( 50, $time );
    }

The overhead compared to JS is expected given that in PHP we delegate the transport to cURL. We will make sure to abstract the transport layer in the future and benchmark several transport layers to offer more solutions to our users.

Please let us know if you manage to optimize this in your environment. Feel free to re-open this issue if you think we can discuss this more.

appkr commented 7 years ago

Hope you find a solution. PHP People will definitely use Algolia then. Thanks.