为什么file_get_contents比memcache_get更快?

7
我正在使用file_get_contents从磁盘加载XML文件,测试后发现,使用file_get_contents()可以在3.99秒内1000次加载156K的文件。我已经子类化了负责加载的部分,并用一个memcache层替换了它,在我的开发机器上,我可以在4.54秒内对同一文档进行1000次加载。
我知道file_get_contents()会执行一些缓存操作,但看起来它实际上比一个众所周知的缓存技术更快。在单台服务器上,file_get_contents()的性能是否达到最佳水平?
我的PHP版本是5.2.17,通过Macports安装,运行在OS X 10.6.8系统上。
编辑:我发现在这种大小的XML文档上,使用MEMCACHE_COMPRESSED标志可以获得一些小的好处。1500次memcache加载在压缩的情况下需要6.44秒(没有压缩需要6.74秒)。然而,两者都比file_get_contents慢,后者在5.71秒内完成相同数量的加载。
3个回答

11
因为file_get_contents对文件进行mmap映射,所以您只需要进行少量的文件系统调用,并且这将最终进入文件系统缓存。而使用memcache会涉及到向memcached发出进程外调用(对于集群实现还会涉及到跨服务器),这会导致性能下降。 file_get_contents() 的性能主要取决于文件系统类型,例如在NFS挂载的文件系统上的文件不会被mmapped,因此访问速度可能会慢很多。 此外,在多用户服务器上,文件系统缓存可能会被其他进程快速刷新,而memcached缓存几乎肯定会在内存中。

啊,有趣。你是说在一个不断加载各种XML文件的Web服务器上,使用memcache方法的性能在某些情况下可能会更好?(我打算部署在低端Linux VPS上,可能只有512MB的RAM - 对于默认的64M memcache保留量来说,还有很多空闲内存。) - halfer
不过,我想知道如果争用会使某些东西从FS缓存中清除,那么它是否同样有可能将某些东西从memcache缓存中清除 ;-) - halfer
在专门为一个应用程序提供的VPS上,您应该能够让所有内容适合。但是值得注意的是“正确调整”缓存:如果32M足够,请使用32M或更少的memcache。确保您的应用程序基于PHP时使用APC或Xcache。不要忘记,如果您使用MySQL,则可以通过调整MySQL缓存获得良好的性能回报... 512Mb足够小,您需要明智地分配。 - TerryE
好的建议,虽然我还有一段距离要部署。不过它应该会是相当低流量的,我想这只是一个副业项目! - halfer
TerryE 点赞,@Mantriur +1 - 两位都非常有帮助。谢谢。 - halfer

3

file_get_contents是检索文件的最简单方法。底层操作系统(尤其是linux)已经具有高效的缓存机制。其他任何操作都会增加开销并减慢速度。

如果你从远程位置加载这些文件,那么使用Memcache是有意义的。

编辑:并不一定file_get_contents是最简单的方式。fopen/fget 可能更快 - 我不确定。但与缓存层的复杂性相比,差异应该很小。


我认为你是正确的。我猜想我本来期望file_get_contents每次执行时都会有一些磁盘活动(也许是为了检查文件是否已更改),而memcache_get则根本不需要进行任何操作。因此,我期望使用memcache方法会更快...尽管如此,这并不是浪费时间,因为我认为我刚刚学到了一些东西 :) - halfer
在非常一般化的层面上,文件系统高速缓存执行的操作与您的PHP内存缓存相同——但它更加专业化,而且不是用脚本语言编写的。:) 高速缓存无需再次访问文件,除非文件内容已更改。 如果系统刷新文件缓存时有大量IO活动,则单独的缓存机制会很有意义。 - Mantriur
给@TerryE打个勾,给Mantriur加个+1——两位都非常有帮助。谢谢。 - halfer

0

在我的看法中,将XML文件存储在内存缓存中没有太多意义。

我宁愿存储解析后的值,既可以节省读取时间,也可以避免重复解析。


看起来你混淆了存储格式,也不知道如何正确使用它们。将XML对象序列化只是很奇怪的做法。在memcache中存储数组也是多余的,因为它本身就是一个数组。 - Your Common Sense
是不是磨损 - 这只是描述将XML文件存储在内存中的混乱情况。 - Your Common Sense

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接