我使用PHP进行大量数据处理(意识到我可能正在进入应该使用其他语言和/或技术的领域)。
我正在使用一个PHP进程进行实体提取,该进程将一个包含ngrams的数组加载到内存中。该阵列使用3GB的内存,每次启动进程大约需要20秒才能加载。我在机器上本地生成一次它,每个进程都从.json文件加载它。然后,每个进程都对正在处理的文本进行标记,并在这两个数组之间进行array_entersection以提取实体。
有没有任何方法可以将其预加载到运行所有这些进程的机器上的内存中,然后在所有进程之间共享资源?
由于PHP可能不可能做到这一点:我应该研究什么类型的语言/方法才能更有效地进行这种实体提取?
如果数组在加载后从未被修改,那么您可以使用pcntl_fork()并派生出一堆脚本副本。使用写时复制语义,它们都将从数组的完全相同的内存副本中读取。
然而,一旦数组被修改,您就会付出巨大的代价,因为数组会被复制到每个分叉子级的内存空间中。如果任何脚本提前完成运行,情况尤其如此——它们会关闭,PHP进程会开始关闭清理,这将被视为对数组内存空间的写入,从而导致复制。
在您的情况下,最好的共享方式可能是只读mmap访问。
我不知道这在PHP中是否可行。许多语言都允许您将文件mmap到内存中,并且您的操作系统将足够智能,可以实现只读映射的共享。此外,如果您不需要全部内存,操作系统可以回收内存,并在必要时从磁盘再次加载。事实上,它甚至可以让你映射比你实际拥有的更多的内存。
mmap
真的很优雅。但无论如何,在PHP中处理这样的映射数据可能是一件痛苦的事。一般来说,PHP速度较慢。在基准测试中,PHP的运行时间通常是一个好的C程序的40-50倍。这比Java要糟糕得多,Java中一个好的Java程序的速度只有高度优化的C程序的两倍;在那里,拥有强大的Java开发工具可能会有回报,而不是必须调试低级C代码。但是PHP没有任何关键的好处:它既不优雅,也没有高级的工具链,也不快速。。。