php mysql和c,MySQL插入,PHP比C更快,这是预期的吗?

最近我的任务是做一些速度检查,所以我可以判断是否更快使用php / php-cli或c将一定数量的行插入数据库.

在开始之前,让我告诉你一些细节,以便一切都清楚:

> php部分通过Apache运行,直接在浏览器中请求.

>正在运行的硬盘驱动器测试是SSD驱动器.我猜常规驱动器的速度会慢一些.这台机器本身并不特别,六年左右.

>所有插入都是通过准备好的声明完成的.我们在php和mysqlcppconn(由Oracle提供的mysql c连接器)上使用mysqli.

>所有插入都是通过输入完成的.我知道我们可以叠加它们,但我们正在这里进行测试.

>时间通过PHP中的microtime和c中的标题显示.

>当然,代码本身并不等同.稍后会详细介绍.

>所有文本都是UTF-8.那里有俄语,中文,阿拉伯语,西班牙语,英语和各种疯狂的东西. mysql表位于utf8_4mb中.

> c代码的数字是使用std :: vector和-O2级别用g编译的结果(向量优于map,unordered_maps和std :: arrays).

所以,这是一个过程:

>连接到数据库.

>打开包含N行的文本文件.

>读取文件的一行.

>拆分分隔符上的行.

>使用分割线的某些部分来获取插入值(例如,第0个,第1个和第3个索引).

>将这些部分发送到准备好的声明中以插入它们.

>重复,直到完全读取文件.

两个代码都完全按预期工作.以下是结果数字:

PHP:

> 5000个条目:1.42 – 1.27秒.

> 20000个条目:5.53 – 6.18秒.

> 50000个参赛作品:14.43 – 15.69秒.

C :

> 5000个条目:1.78 – 1.81秒.

> 20000个条目:7.19 – 7.22秒.

> 50000个参赛作品:18.52 – 18.84秒.

php优于c,因为文件中的行增加…首先,我怀疑行拆分功能:php中的拆分是用“爆炸”完成的.算法和c一样天真……容器通过引用传递,其内容在运行中更改.容器只遍历一次.我确保容器“reserve()”所有必要的空间(记住,我最终选择向量)是固定的.容器在main函数上创建,然后通过代码通过引用传递.它永远不会被清空或调整大小:只有它的内容会改变.

template void explode(const std::string& p_string, const char p_delimiter, container& p_result)

{

auto it=p_result.begin();

std::string::const_iterator beg=p_string.begin(), end=p_string.end();

std::string temp;

while(beg < end)

{

if( (*beg)==p_delimiter)

{

*(it)=temp;

++it;

temp="";

}

else

{

temp+=*beg;

}

++beg;

}

*(it)=temp;

}

如前所述,执行的任务是等效的,但生成它的代码不是. C代码具有通常的try-catch块来控制mysql交互.至于其余部分,主循环运行直到达到EOF并且每次迭代检查插入是否失败(在c和php中).

我已经看到c在处理文件及其内容时大大优于php,所以我希望在这里适用.不知怎的,我怀疑分裂算法,但也许只是数据库连接器速度较慢(仍然,当我禁用数据库交互时php仍然处理得更快)或者我的代码是低于…

对于分析,gprof对c代码进行了讨论:

Each sample counts as 0.01 seconds.

% cumulative self self total

time seconds seconds calls ns/call ns/call name

60.00 0.03 0.03 50000 600.00 600.00 void anc_str::explotar_cadena<:vector std::allocator> > >(std::string const&, char, std::vector<:string std::allocator> >&)

40.00 0.05 0.02 insertar(sql::PreparedStatement*, std::string const&, std::vector<:string std::allocator> >&)

0.00 0.05 0.00 1 0.00 0.00 _GLOBAL__sub_I__ZN7anc_str21obtener_linea_archivoERSt14basic_ifstreamIcSt11char_traitsIcEE

其中“explotar_cadena”是“爆炸”而“insertar”是“拆分此行并将准备好的声明设置为”.正如你所看到的那样,60%的时间都花在那里(这并不奇怪…它运行了50000次并且做了这个疯狂的分裂事情). “obtener_linea_archivo”只是“请将下一行转储到字符串中”.

没有mysql交互(只需加载文件,读取行并拆分它们)我得到这些测量结果:

PHP

> 5000个条目:0.019 – 0.036秒.

> 20000个条目:0.09 – 0.10秒.

> 50000个条目:0.14 – 0.17秒.

C

> 5000个条目:0.07 – 0.10秒.

> 20000个条目:0.25 – 0.26秒.

> 50000个条目:0.49 – 0.55秒.

好吧,两次都是好的,现实生活条件几乎不引人注意,我很惊讶……所以这里的问题是:我应该期待这个吗?任何有经验的人都愿意伸出援手吗?

提前致谢.

编辑:这是一个包含输入文件,C代码和PHP代码的精简版本的快速链接[http://www.datafilehost.com/d/d31034d6].请注意,没有sql交互:只有文件打开,字符串拆分和时间测量.请原谅屠宰代码和半西班牙语评论和变量名称,因为这是匆忙完成的.另外,请注意上面的gprof结果:我不是专家,但我认为我们正试图找到一种更好的方法来分割字符串.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值