PHP 使用 curl_* 系列函数和 curl_multi_* 系列函数进行多接口调用时的性能对比

在页面中调用的服务较多时,使用并行方式,即使用 curl_multi_* 系列函数耗时要小于 curl_* 系列函数。

测试环境
操作系统:Windows 10 x64
Server:Apache 2.4.18
PHP:5.6.19
MySQL:5.7.11
cURL:7.47.1

测试数据库选择 MySQL 官方网站的样本数据库 sakila,下载地址:http://dev.mysql.com/doc/index-other.html

测试页面需要调用 3 个 api:

getActorInfo.php

<?php

// 接口1
$dsn = ‘mysql:host=localhost;dbname=sakila‘;
$user = ‘root‘;
$pwd = ‘‘;
try {
    $pdo = new PDO($dsn, $user, $pwd);
} catch(PDOException $e) {
    echo $e->getMessage();
}

$sql = ‘select * from actor limit 0, 100‘;
$query = $pdo->query($sql);
$query->setFetchMode(PDO::FETCH_ASSOC);
$rs = $query->fetchAll();
exit(json_encode($rs));

getAddressInfo.php

<?php

// 接口2
$dsn = ‘mysql:host=localhost;dbname=sakila‘;
$user = ‘root‘;
$pwd = ‘‘;
try {
    $pdo = new PDO($dsn, $user, $pwd);
} catch(PDOException $e) {
    echo $e->getMessage();
}

$sql = ‘select * from address limit 0, 100‘;
$query = $pdo->query($sql);
$query->setFetchMode(PDO::FETCH_ASSOC);
$rs = $query->fetchAll();
exit(json_encode($rs));

getCityInfo.php

<?php

// 接口3
$dsn = ‘mysql:host=localhost;dbname=sakila‘;
$user = ‘root‘;
$pwd = ‘‘;
try {
    $pdo = new PDO($dsn, $user, $pwd);
} catch(PDOException $e) {
    echo $e->getMessage();
}

$sql = ‘select * from city limit 0, 100‘;
$query = $pdo->query($sql);
$query->setFetchMode(PDO::FETCH_ASSOC);
$rs = $query->fetchAll();
exit(json_encode($rs));

首先使用 curl_* 系列函数调用这3个接口:

<?php

list($usec, $sec) = explode(" ", microtime());
$start = (float)$usec + (float)$sec;

$api = [];
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getCityInfo.php‘;
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getAddressInfo.php‘;
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getActorInfo.php‘;

$ch = [];
foreach($api as $key    =>    $val) {
    $ch[$key] = curl_init($val);
    curl_setopt($ch[$key], CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch[$key]);
    curl_close($ch[$key]);
    var_dump($result);
}

list($usec, $sec) = explode(" ", microtime());
$end = (float)$usec + (float)$sec;

$seconds = $end - $start;
echo ‘耗时‘,$seconds,‘秒‘;

分别取5次耗时的平均值:

第1次 第2次 第3次 第4次 第5次 平均
0.055s 0.046s 0.058s 0.049s 0.052s 0.052s

再使用 curl_multi_* 系列函数调用这3个接口

<?php

list($usec, $sec) = explode(" ", microtime());
$start = (float)$usec + (float)$sec;

$api = [];
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getCityInfo.php‘;
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getAddressInfo.php‘;
$api[] = ‘http://127.0.0.3/php/high-performance/5/curl/api/getActorInfo.php‘;

$ch = [];
foreach($api as $key    =>    $val) {
    $ch[$key] = curl_init($val);
    curl_setopt($ch[$key], CURLOPT_RETURNTRANSFER, TRUE);
}

// 多个cURL资源加入到$mh句柄中
$mh = curl_multi_init();
foreach($ch as $key => $val) {
    curl_multi_add_handle($mh, $ch[$key]);
}

// 执行批处理等待全部完成
$running = null;
do {
    curl_multi_exec($mh, $running);
} while($running);

// 待完成后 获取返回的内容
foreach($ch as $key => $val) {
    $result = curl_multi_getcontent($ch[$key]);
    var_dump($result);
    // 关闭各个句柄
    curl_multi_remove_handle($mh, $ch[$key]);
}

list($usec, $sec) = explode(" ", microtime());
$end = (float)$usec + (float)$sec;

$seconds = $end - $start;
echo ‘耗时‘,$seconds,‘秒‘;
第1次 第2次 第3次 第4次 第5次 平均
0.038s 0.049s 0.038s 0.026s 0.027s 0.0356s

使用 curl_* 系列函数多接口调用5次的平均耗时是0.052秒,使用curl_multi_*系列函数多接口调用5次的平均耗时是0.0356秒。

时间: 2024-10-26 04:31:00

PHP 使用 curl_* 系列函数和 curl_multi_* 系列函数进行多接口调用时的性能对比的相关文章

默认形参在函数定义阶段就已经被赋值,在调用时就可以不用再次赋值了。

'''默认形参 在函数定义阶段,就已经被赋值了. def func(x,y=10): if x > y: return x return y ms=func(2) print(ms) 特点: 在函数定义阶段就已经被赋值,意味着在调用时可以不用为其再次赋值了. 注意注意注意!!!: 1.位置形参必须放在默认形参的左边. 2.默认形参的值只在定义阶段赋值一次,也就是说默认参数的值 在函数定义阶段就已经固定了. 案例如下: m=15 def foo(x=m): print(x) m=200 foo()

多态实现--虚函数与纯虚函数

多态实现--虚函数与纯虚函数 C++中实现多态是使用虚函数表的方法实现的. 那么具体怎么实现的呢? 举例说明 假设有这样一个多态场景: 有一个基类动物(animal类),动物里面又有两个派生类:猫(cat类)和狗(dog类).现在要求动物类有一个共同的方法:叫声(voice成员函数),但猫和狗叫声是不同的(即:它们的叫声实现方法不同). 那么代码怎么写呢? 多态的代码实现 #include <iostream> using namespace std; //1. 定义一个纯虚函数 class

第七章、函数基础之定义函数的三种方式03

目录 第七章.函数基础之定义函数的三种方式03 一.无参函数 二.有参函数 三.空函数 第七章.函数基础之定义函数的三种方式03 一.无参函数 定义函数时参数是函数体接收外部传值的一种媒介 在函数阶段括号没有参数就是无参函数.调用时不需要传入实参 如果函数体代码逻辑不需要依赖外部传入值,必须定义成无参函数 def func(): print('hello nick') func() # hello nick 二.有参函数 在函数阶段括号有参数就是有参函数.调用时需要传入实参 如果函数体代码逻辑需

浅析php curl_multi_*系列函数进行批量http请求

何起: 一系列 数量很大 数据不热 还希望被蜘蛛大量抓取的页面,在蜘蛛抓取高峰时,响应时间会被拉得很高. 前人做了这样一个事儿:页面分3块,用3个内部接口提供,入口文件用curl_multi_*系列函数抓取3个内部接口的内容,拼成一个页面. 怀疑这样做会有影响性能的可能. 故学而分析之. 看了php官方手册,总结批量调用过程如下: curl_multi_init — 返回一个新cURL批处理句柄,作为curl_init生成的单个curl句柄的容器 curl_multi_add_handle — 

使用file_get_content系列函数和使用curl系列函数采集图片的性能对比

由于公司的一个汽车网站的后台的汽车内容都是主要是来自与汽车之家的,编辑的同事们必须天天手动去对着汽车之家来添加汽车,实在是太蛋疼了.于是乎,为了改变这种状况,作为一个开发码农,我的任务就来了...那就是准备做一个功能,只要粘贴对应的汽车之家的网址url就能对这些数据进行自动填充到我们后台的表单中,目前基本的填充都实现了,但是还是没有能够把对应的汽车相册采集进来. 采集图片的功能我以前也做过,但是汽车之家大部分的汽车都有挺多图片的,开始的时候,我打算使用以前的采集图片的办法,也就是使用file_g

【函数】Oracle函数系列(1)--字符函数

[函数]Oracle函数系列(1)--字符函数 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 常见字符函数(lower.upper.initcap.concat.substr.length.intr.lpad.rpad.trim.chr.ascii.replace.translate)的使用 ② 判断字符串中是否含有汉字 ③ substr和instr的联合使用 ④

微软100题系列之-----设计包含min函数的栈

题意: 定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素. 要求函数min.push 以及pop 的时间复杂度都是O(1). 思路:定义两个栈,一个用来记录数据的插入和删除,一个用来存储最小值的变化 代码如下: template <class T> class Stack { public: Stack(int len=100); T Min(); T Pop(); void Push(T val); private: T top1,top2; T *stack1,*stack

深入理解this机制系列第三篇——箭头函数

× 目录 [1]痛点 [2]解决 [3]基本用法[4]回调函数[5]注意事项 前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将介绍ES6新增的内容——箭头函数 痛点 对于闭包的痛点在于,闭包的this默认绑定到window对象,但又常常需要访问嵌套函数的this,所以常常在嵌套函数中使用var that = this,然后在闭包中使用that替代this,使用作用域查找的方法来找到嵌套函数的this值 var a = 0;

curl数据采集系列之单页面采集函数get_html

在做数据采集时经常要使用到curl+正则的方式采集需要的数据 根据自己的工作经验 把自己写的一些常用自定义函数 拿到博客园来分享 如果有写得不恰当的地方 请多多指教 这是一个系列 没办法在一两天写完 所以一篇一篇的发布 大致大纲: 1.curl数据采集系列之单页面采集函数get_html 2.curl数据采集系列之多页面并行采集函数get_htmls 3.curl数据采集系列之正则处理函数get _matches 4.curl数据采集系列之代码分离 5.curl数据采集系列之并行逻辑控制函数we