6

just wondering when it comes to just the basic GET/POST. (i.e something simple as getting the users profile and not something complicated like getting a pictures from every album)

which is faster? Graph or FQL.

i know FQL is newer than graph, but unsure if its more efficient.

Juicy Scripter
  • 25,778
  • 6
  • 72
  • 93
Nate
  • 1,630
  • 2
  • 24
  • 41
  • not really an answer, but I think the latency of network is more of the concern, compared to the latency of CPU processing. Facebook must have good cache policy to speed things up. – Hoàng Long Oct 04 '11 at 06:56

2 Answers2

17

It's in no way comparable like this. While you can get same data (in some cases) from both their intents are completely different: FQL is a query language, Graph is an API.

Calling to FQL query if using new JS SDK is a Graph API call itself...

You can (and probably should, if you worry about real comparison and not theoretical speculation) compare speed of calls returning same data but you should take into account some things:

  • Graph API still sucks at data filtering conditions and aggregation of data
  • FQL just can't provide you too many of functionality required in today's applications (like Real-Time updates)
  • Graph API have an ability batch calls, which may speed up things a lot, this also can be used to call fql.query and fql.multiquery (in a bit cumbersome way).
  • Graph API rocks at data filtering with Field Expansion

Consider following example from FQL documentation, subquery that fetches all user information for the active user and friends:

SELECT uid, name, pic_square FROM user WHERE uid = me()
OR uid IN (SELECT uid2 FROM friend WHERE uid1 = me())

This simply not possible to achieve with a single Graph API call. (see Update)

Once you define desired subset of data to get you can choose appropriate method of retrieval based on your requirements.

BTW, FQL is much older than Graph, we had it aside to FBML (rip) and FBJS (rip)

Update:

Graph API providing way for Batch Requests and specifying dependencies between operations in the request. For example same sample as above can be achieved in a single call to Graph API

POST https://graph.facebook.com/
POST Data:
batch=[
  {
    "method": "GET",
    "name" : "get-friends",
    "relative_url": "me/friends?fields=id",
  },
  {
    "method": "GET",
    "relative_url": "?ids={result=get-friends:$.data.*.id}&fields=id,name,picture"
  }
]

Update 2:
As of 30 August 2012 Graph API is also support Field Expansion as additional (very powerful) mechanism of data retrieval (including nested data)

Juicy Scripter
  • 25,778
  • 6
  • 72
  • 93
  • That example is bad because you could do that with a graph call. But still goods. The only thing missing is you can do batch requests with graph api which can help with speed in some cases. – bkaid Oct 04 '11 at 06:14
  • You can do that with **two** graph calls, one to get list of friends ids, and second to return desired data-set. I agree that this example almost have no sense in real life (name and id of current user is probably something you already have, a)nd pic_square can be mimicked with http://graph.facebook.com/USER_ID/picture?type=square) – Juicy Scripter Oct 04 '11 at 06:58
  • You can do batch graph-calls (up to 50 graph calls packed into one) which can even reference each others results. Pretty close to multiquery, huh. In fact, batch graph calls can include FQL queries. https://developers.facebook.com/docs/reference/api/batch/ – nisc Dec 25 '11 at 23:20
  • @nisc, batch is a cool thing, but as I said above it wouldn't help you much with request which input is another request output (dependent) – Juicy Scripter Dec 26 '11 at 04:14
  • 1
    @Juicy Scripter Luckily, you're wrong :-) »Often, the operations in the request are dependent - for example, the output of one operation may be used in the input of the next operation. The graph Batch API has support for this using the JSONPath expression format.« – nisc Dec 26 '11 at 08:31
  • @nisc, whoa, You're totally right. I wasn't updated on this and not visited this page for a while, thanks for pointing on this thing. – Juicy Scripter Dec 26 '11 at 09:36
3

I ran a simple test (getting the cover photo id) using the PHP SDK :

public $microtime_start = 0;

public function getExecutionTime() {
    return round(microtime(true) - $this->microtime_start, 4);
}

public function getFQL($request, $filter = true, $multiFilter = true) {
    if(is_array($request)) {
        $query = '{';
        foreach ($request as $key => $q) {
            $query .= '"'.urlencode($key).'":"'.urlencode(addslashes($q)).'",';
        }
        $query = substr($query, 0, -1).'}';
        $data = $this->callAPI('/fql?q=' . $query);
        if($filter) {
            $data = $data['data'];
            if($multiFilter) {
                $data = $data[count($data)-1]['fql_result_set'];
            }
            return $data;
        }
    } else {
        $data = $this->callAPI('/fql?q=' . urlencode($request));
        if($filter) {
            return $data['data'];
        }
    }
}

public function callAPI($path) {
    $params = array('access_token' => $this->getAccessToken());
    return $this->api($path, 'GET', $params);
}

public function getCoverPhotoId($uid) {
    $time = $this->getExecutionTime();

    $albums = $this->api("/me/albums");
    $album_id = "";
    foreach ($albums["data"] as $item) {
        if ($item["name"] == "Cover Photos") {
            $album_id = $item["id"];
            $profile_picture_id = $item["cover_photo"];
            break;
        }
    }
    $time2 = $this->getExecutionTime();
    echo 'graph api: '.($time2 - $time).'<br/>';

    $data = $this->getFQL(array(
        'query1' => 'SELECT cover_object_id FROM album WHERE owner = ' . $uid.' AND name = "Cover Photos"'
    ));
    $time3 = $this->getExecutionTime();
    echo 'graph api with FQL: '.($time3 - $time2).'<br/>';

    $data = $this->api(
            array(
                'method' => 'fql.query',
                'query' => 'SELECT cover_object_id FROM album WHERE owner = ' . $uid.' AND name = "Cover Photos"'
            )
    );

    $time4 = $this->getExecutionTime();
    echo 'FQL via rest api: '.($time4 - $time3).'<br/>';
}

Results :

graph api: 1.28320002556

graph api with FQL: 0.744100093842

FQL via rest api: 0.544199943542

The basic FQL is much faster, the FQL via graph api is ok, but graph api is waaay too slow... And you will get a bunch of useless stuff with the graph api

Olivier
  • 1,270
  • 1
  • 10
  • 24