From aba64a0b81853dd3153da708538dddc96bbe647d Mon Sep 17 00:00:00 2001
From: Markus Goetz <markus@woboq.com>
Date: Sat, 17 Aug 2013 16:01:37 +0200
Subject: [PATCH] Class Auto Loader: Cache paths in APC

Using benchmark_single.php (from administration repo) I can
measure a speed improvement of 5% to 20% loading the /index.php
when logged in. (when using APC and php-fpm).
---
 lib/autoloader.php       | 26 +++++++++++++++++++++++++-
 lib/memcache/factory.php | 29 +++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/lib/autoloader.php b/lib/autoloader.php
index 2117063909..01841f831b 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -111,15 +111,39 @@ class Autoloader {
 	 * @param string $class
 	 * @return bool
 	 */
+	protected $memoryCache = null;
+	protected $constructingMemoryCache = true; // hack to prevent recursion
 	public function load($class) {
-		$paths = $this->findClass($class);
+		// Does this PHP have an in-memory cache? We cache the paths there
+		if ($this->constructingMemoryCache && !$this->memoryCache) {
+			$this->constructingMemoryCache = false;
+			$this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader');
+		}
+		if ($this->memoryCache) {
+			$pathsToRequire = $this->memoryCache->get($class);
+			if (is_array($pathsToRequire)) {
+				foreach ($pathsToRequire as $path) {
+					require_once $path;
+				}
+				return false;
+			}
+		}
 
+		// Use the normal class loading path
+		$paths = $this->findClass($class);
 		if (is_array($paths)) {
+			$pathsToRequire = array();
 			foreach ($paths as $path) {
 				if ($fullPath = stream_resolve_include_path($path)) {
 					require_once $fullPath;
+					$pathsToRequire[] = $fullPath;
 				}
 			}
+
+			// Save in our memory cache
+			if ($this->memoryCache) {
+				$this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec
+			}
 		}
 		return false;
 	}
diff --git a/lib/memcache/factory.php b/lib/memcache/factory.php
index 4c1b1ab207..fde7d94756 100644
--- a/lib/memcache/factory.php
+++ b/lib/memcache/factory.php
@@ -37,4 +37,33 @@ class Factory {
 	public function isAvailable() {
 		return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable() || Memcached::isAvailable();
 	}
+
+	/**
+	 * get a in-server cache instance, will return null if no backend is available
+	 *
+	 * @param string $prefix
+	 * @return \OC\Memcache\Cache
+	 */
+	public static function createLowLatency($prefix = '') {
+		if (XCache::isAvailable()) {
+			return new XCache($prefix);
+		} elseif (APCu::isAvailable()) {
+			return new APCu($prefix);
+		} elseif (APC::isAvailable()) {
+			return new APC($prefix);
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * check if there is a in-server backend available
+	 *
+	 * @return bool
+	 */
+	public static function isAvailableLowLatency() {
+		return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable();
+	}
+
+
 }
-- 
GitLab