## 性能
当涉及到性能时,使用PINQ有两种截然不同的情况。
* 内存查询
当利用Traversable或Collection查询在内存中执行时,这些操作的开销应该很少。显然,如果数据集是大得出奇的,你可能会遇到问题。但是对于大多数用例来说,由于延迟查询和高效的迭代器使用,实际上会带来可观的性能优势。
* 外部查询
对于任何一个Queryable或者Repository,都有令人担忧的问题。当查询这些接口的实现时,为了准确地解释它们,它们所提供的函数将被解析为表达式树。这是一个非常昂贵的过程,如果没有正确的设置这些接口的实现,可能会导致显着的性能损失。
### 缓存查询的解析过程
为了解决"将接口实现解析为表达式树这个耗时过程"的问题,提供了几个选项。配置Pinq\Caching\CacheProvider类设置默认缓存机制:
* 文件缓存(File Cache) - 将数据缓存在单个文件中,这对于高并发性来说不是最佳的,但适合于那些无法访问正确的内存缓存的用户。
~~~
\Pinq\Caching\CacheProvider::setFileCache($filePath);
~~~
* 目录缓存(Directory Cache) - 将数据缓存在目录的多个文件中,并发性可能相对较好,但性能不佳,应优先使用适当的内存缓存。
~~~
\Pinq\Caching\CacheProvider::setDirectoryCache($directoryPath);
~~~
* 教条缓存(Doctrine Cache)- 这允许您使用实现了缓存适配器接口的组件中的任何缓存。
~~~
\Pinq\Caching\CacheProvider::setDoctrineCache($cacheImplementation);
~~~
* 数组访问缓存(ArrayAccess Cache) - 这允许您使用任何实现数组访问接口的对象的缓存。
~~~
\Pinq\Caching\CacheProvider::setArrayAccessCache($cacheImplementation);
~~~
* 自定义缓存(Custom Cache) - 允许使用任何实现Pinq\Caching\ICacheAdapter接口的缓存。
~~~
\Pinq\Caching\CacheProvider::setCustomCache($cacheImplementation);
~~~
所有上述选项将通过消除在每个请求上都需要进行查询解析的需要来显着降低性能损失。应该使用适当的内存缓存(如 Memcache或Redis),来替代文件/目录缓存。但是文件/目录缓存对小型应用程序是足够的,只需要磁盘访问,而不需要设置真正的缓存那么麻烦。
### 在开发阶段
在开发过程中使用缓存可能会有问题,因为查询更改时,可能会被忽略,并继续使用原始版本。所以在开发阶段你应该使用:
~~~
\Pinq\Caching\CacheProvider::setDevelopmentMode(true);
~~~
当此标志设置为true时,缓存将在每次请求时被清除。但请记住在开始部署到正式的生产环境之前将其禁用。