Add a single character cache to WidthCache
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 22:39:02 +0000 (22:39 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 22:39:02 +0000 (22:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=112084

Patch by Benjamin Poulain <bpoulain@apple.com> on 2013-03-12
Reviewed by Geoffrey Garen.

More than half of the values stored in WidthCache are values
for a single character.

Previously, we were creating a new SmallStringKey for each one of
them, causing a lot of extra memory operations even for the simple
cases.

This patch adds a second map, m_singleCharMap, to simplify the
computation for the common case of a single char TextRun.

* platform/graphics/WidthCache.h:
(WebCore::WidthCache::clear):
(WidthCache):
(WebCore::WidthCache::addSlowCase):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@145601 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/WidthCache.h

index 4c01bb4..2f46ede 100644 (file)
@@ -1,3 +1,25 @@
+2013-03-12  Benjamin Poulain  <bpoulain@apple.com>
+
+        Add a single character cache to WidthCache
+        https://bugs.webkit.org/show_bug.cgi?id=112084
+
+        Reviewed by Geoffrey Garen.
+
+        More than half of the values stored in WidthCache are values
+        for a single character.
+
+        Previously, we were creating a new SmallStringKey for each one of
+        them, causing a lot of extra memory operations even for the simple
+        cases.
+
+        This patch adds a second map, m_singleCharMap, to simplify the
+        computation for the common case of a single char TextRun.
+
+        * platform/graphics/WidthCache.h:
+        (WebCore::WidthCache::clear):
+        (WidthCache):
+        (WebCore::WidthCache::addSlowCase):
+
 2013-03-12  Philip Rogers  <pdr@google.com>
 
         Replace static_casts for SVG transformable and locatable elements
index 25e76b4..114837f 100644 (file)
@@ -144,20 +144,38 @@ public:
         return addSlowCase(run, entry);
     }
 
-    float* addSlowCase(const TextRun& run, float entry)
+    void clear()
     {
-        SmallStringKey smallStringKey;
-        if (run.is8Bit())
-            smallStringKey = SmallStringKey(run.characters8(), run.length());
-        else
-            smallStringKey = SmallStringKey(run.characters16(), run.length());
+        m_singleCharMap.clear();
+        m_map.clear();
+    }
 
-        Map::AddResult addResult = m_map.add(smallStringKey, entry);
+private:
+    float* addSlowCase(const TextRun& run, float entry)
+    {
+        int length = run.length();
+        bool isNewEntry;
+        float *value;
+        if (length == 1) {
+            SingleCharMap::AddResult addResult = m_singleCharMap.add(run[0], entry);
+            isNewEntry = addResult.isNewEntry;
+            value = &addResult.iterator->value;
+        } else {
+            SmallStringKey smallStringKey;
+            if (run.is8Bit())
+                smallStringKey = SmallStringKey(run.characters8(), length);
+            else
+                smallStringKey = SmallStringKey(run.characters16(), length);
+
+            Map::AddResult addResult = m_map.add(smallStringKey, entry);
+            isNewEntry = addResult.isNewEntry;
+            value = &addResult.iterator->value;
+        }
 
         // Cache hit: ramp up by sampling the next few words.
-        if (!addResult.isNewEntry) {
+        if (!isNewEntry) {
             m_interval = s_minInterval;
-            return &addResult.iterator->value;
+            return value;
         }
 
         // Cache miss: ramp down by increasing our sampling interval.
@@ -165,23 +183,24 @@ public:
             ++m_interval;
         m_countdown = m_interval;
 
-        if (m_map.size() < s_maxSize)
-            return &addResult.iterator->value;
+        if ((m_singleCharMap.size() + m_map.size()) < s_maxSize)
+            return value;
 
-        m_map.clear(); // No need to be fancy: we're just trying to avoid pathological growth.
+        // No need to be fancy: we're just trying to avoid pathological growth.
+        m_singleCharMap.clear();
+        m_map.clear();
         return 0;
     }
 
-    void clear() { m_map.clear(); }
-
-private:
     typedef HashMap<SmallStringKey, float, SmallStringKeyHash, SmallStringKeyHashTraits> Map;
+    typedef HashMap<UChar, float> SingleCharMap;
     static const int s_minInterval = -3; // A cache hit pays for about 3 cache misses.
     static const int s_maxInterval = 20; // Sampling at this interval has almost no overhead.
     static const int s_maxSize = 500000; // Just enough to guard against pathological growth.
 
     int m_interval;
     int m_countdown;
+    SingleCharMap m_singleCharMap;
     Map m_map;
 };