]> source.dussan.org Git - nextcloud-server.git/commitdiff
Performance improvements for NaturalSort
authorRobin McCorkell <rmccorkell@karoshi.org.uk>
Tue, 20 Jan 2015 12:40:18 +0000 (12:40 +0000)
committerRobin McCorkell <rmccorkell@karoshi.org.uk>
Mon, 9 Feb 2015 16:32:43 +0000 (16:32 +0000)
A combination of using isset() instead of count() or strlen(), caching the
chunkify function, and replacing is_numeric() with some comparisons

lib/private/naturalsort.php

index 6e259630f79db6a25e92e634ca580853ca5db929..d511bfa3f6615132512868addc93f8416c272e87 100644 (file)
@@ -12,6 +12,7 @@ namespace OC;
 class NaturalSort {
        private static $instance;
        private $collator;
+       private $cache = array();
 
        /**
         * Split the given string in chunks of numbers and strings
@@ -21,13 +22,15 @@ class NaturalSort {
        private function naturalSortChunkify($t) {
                // Adapted and ported to PHP from
                // http://my.opera.com/GreyWyvern/blog/show.dml/1671288
+               if (isset($this->cache[$t])) {
+                       return $this->cache[$t];
+               }
                $tz = array();
                $x = 0;
                $y = -1;
                $n = null;
-               $length = strlen($t);
 
-               while ($x < $length) {
+               while (isset($t[$x])) {
                        $c = $t[$x];
                        // only include the dot in strings
                        $m = ((!$n && $c === '.') || ($c >= '0' && $c <= '9'));
@@ -40,6 +43,7 @@ class NaturalSort {
                        $tz[$y] .= $c;
                        $x++;
                }
+               $this->cache[$t] = $tz;
                return $tz;
        }
 
@@ -75,14 +79,13 @@ class NaturalSort {
                // instead of ["test.txt", "test (2).txt"]
                $aa = self::naturalSortChunkify($a);
                $bb = self::naturalSortChunkify($b);
-               $alen = count($aa);
-               $blen = count($bb);
 
-               for ($x = 0; $x < $alen && $x < $blen; $x++) {
+               for ($x = 0; isset($aa[$x]) && isset($bb[$x]); $x++) {
                        $aChunk = $aa[$x];
                        $bChunk = $bb[$x];
                        if ($aChunk !== $bChunk) {
-                               if (is_numeric($aChunk) && is_numeric($bChunk)) {
+                               // test first character (character comparison, not number comparison)
+                               if ($aChunk[0] >= '0' && $aChunk[0] <= '9' && $bChunk[0] >= '0' && $bChunk[0] <= '9') {
                                        $aNum = (int)$aChunk;
                                        $bNum = (int)$bChunk;
                                        return $aNum - $bNum;
@@ -90,7 +93,7 @@ class NaturalSort {
                                return self::getCollator()->compare($aChunk, $bChunk);
                        }
                }
-               return $alen - $blen;
+               return count($aa) - count($bb);
        }
 
        /**