PHP + pthreads : Build one big object - parallel-processing

标签 php multithreading performance parallel-processing pthreads

最近,我的 php 应用程序尝试使用一万多行 CSV 数据执行一些操作,但遇到了一些严重的性能问题。 基本上我有大约十个函数,由不同的 preg_match/preg_replace 操作组成,这些操作处理解析的 csv 数据的每一行的一列(NLP DateParser、各种字符串修改内容、来自 html 源的图像识别等)。

因为我正在达到脚本处理速度非常慢(50 到 120 秒之间)以及内存问题(过于复杂的对象)的范围,现在是时候进行一些性能改进了;)

所以我想到了 pthreads,它允许在 php 脚本中使用多线程。但我不太确定这是否对我的情况有帮助,或者只是产生比它解决的更多的性能问题(通过线程处理的开销):

我的想法是循环遍历所有一万行,并为每个列处理步骤启动一个线程(10k 行 + 10 列 = 10k * 10 = 100.000 个线程)。您认为这会带来性能提升吗? 或者我应该将 csv 数据分割成 block (假设 200 行),这些 block 将在单独的线程中处理(10k 行/200 block = 50 个线程)?

我会附上一张由我分析的 php 脚本组成的图像,您可以在其中看到哪些函数消耗了很多时间,但遗憾的是我没有足够的声誉点:/

并行处理有潜力吗?我可以直接从不同的线程向同一个对象添加属性,还是必须先同步(因此等待线程完成)?是否可以在多个线程中读取同一文件(第一百行线程 1,第二百行在线程 2 等),并在所有处理步骤结束时构建一个包含所有行的大对象?

我希望我糟糕的英语不会妨碍你理解我的想法和问题......

感谢您的建议!

mfuesslin

编辑:我不确定瓶颈:猜测最大的瓶颈是处理所有 csv 数据产生的大对象...Profiler 引起了我对一些冗余 foreach 循环的注意我可以忽略这一点。 但主要问题是我必须处理的数据量。所有处理函数都不需要那么多时间(但是如果你连续处理 10k...)。

使用内存数据库而不是 csv 进行操作的想法很好 - 将尝试一下。

preg_* 函数不能用 str_* 函数替换,因为我需要模式识别。

我还将尝试 Gearman 并尝试将每个数据处理步骤分离到各个作业中。

PHP 版本为 5.6.10,启用了 opcache。

最佳答案

听起来你想拿出一把非常大的枪。我不确定 pthreads 是否能解决所有问题。我不会详细介绍如何应用pthreads,因为这里发生了很多事情,而且似乎现有的解决方案还有一些改进的空间。

  • 瓶颈到底在哪里?您是否分析了代码并解决了瓶颈?
  • CSV
    • 也许您可以删除它并将 CSV 数据导入到数据库中?
    • 例如,使用 SQLite 内存数据库进行处理怎么样
    • 您是否通过使用分块解析来降低 CSV 解析器的内存占用?
  • 您正在使用 preg_*() 函数:尝试将其替换为字符串函数
  • 将数据处理职能拆分为明确定义的单独工作
  • 使用作业/队列系统进行处理,例如
  • 你的 PHP 怎么样?升级到5.6? opcache 启用了吗?

关于PHP + pthreads : Build one big object - parallel-processing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30954216/

相关文章:

php - 如何执行具有多个条件的通用代码

php - 如何在 Codeigniter 中检查 session 是否已设置?

c++ - 如何使用一个 std::thread 对象来运行 2 个顺序事件(函数)?

multithreading - Julia 多线程无法扩展令人尴尬的并行作业

php - CodeIgniter DataMapper 表名覆盖不起作用

javascript - 如何根据选择其他选择选项来更改选择选项

c++ - 信号唤醒线程

performance - 即使对于很短的if语句主体,分支预测错误也会刷新整个管道吗?

objective-c - 可变数组,Objective-c,或可变数组,c。性能上有什么区别吗?

PHP 允许的内存大小 内存大小耗尽