diff --git a/src/contact.cpp b/src/contact.cpp
index d3a7fa59d33a8d015ed4361807a3ae8f893f12e9..8a8513bf0d1013b71f3cf64c65f79e0bacb8da73 100644
--- a/src/contact.cpp
+++ b/src/contact.cpp
@@ -49,6 +49,11 @@ public:
    AbstractContactBackend* m_pBackend       ;
    bool                    m_isPlaceHolder  ;
 
+   //Cache
+   QString m_CachedFilterString;
+
+   QString filterString();
+
    //Helper code to help handle multiple parents
    QList<Contact*> m_lParents;
 
@@ -61,8 +66,29 @@ public:
    void phoneNumberCountAboutToChange(int,int);
 };
 
+QString ContactPrivate::filterString()
+{
+   if (m_CachedFilterString.size())
+      return m_CachedFilterString;
+
+   //Also filter by phone numbers, accents are negligible
+   foreach(const PhoneNumber* n , m_Numbers) {
+      m_CachedFilterString += n->uri();
+   }
+
+   //Strip non essential characters like accents from the filter string
+   foreach(const QChar& char2,QString(m_FormattedName+'\n'+m_Organization+'\n'+m_Group+'\n'+
+      m_Department+'\n'+m_PreferredEmail).toLower().normalized(QString::NormalizationForm_KD) ) {
+      if (!char2.combiningClass())
+         m_CachedFilterString += char2;
+   }
+
+   return m_CachedFilterString;
+}
+
 void ContactPrivate::changed()
 {
+   m_CachedFilterString.clear();
    foreach (Contact* c,m_lParents) {
       emit c->changed();
    }
@@ -352,6 +378,12 @@ time_t Contact::PhoneNumbers::lastUsedTimeStamp() const
    return t;
 }
 
+///Recomputing the filter string is heavy, cache it
+QString Contact::filterString() const
+{
+   return d->filterString();
+}
+
 ///Callback when one of the phone number presence change
 void Contact::slotPresenceChanged()
 {
diff --git a/src/contact.h b/src/contact.h
index a42a982e45bef4295554be0348ed959677d4189f..ff72c500246adbb0d09c5a4e36943e067fb697a7 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -107,6 +107,9 @@ public:
    const QString& department       () const;
    bool  isActive                  () const;
 
+   //Cache
+   QString filterString            () const;
+
    //Number related getters (proxies)
    bool isPresent                  () const;
    bool isTracked                  () const;
diff --git a/src/contactproxymodel.cpp b/src/contactproxymodel.cpp
index 2099aa0605686d8687516766a9c628144eff6928..09c059b9604fb3c941e5f9266baead632b4ed826 100644
--- a/src/contactproxymodel.cpp
+++ b/src/contactproxymodel.cpp
@@ -275,16 +275,8 @@ QVariant ContactProxyModel::data( const QModelIndex& index, int role) const
             return c->isActive();
          case ContactModel::Role::DatedLastUsed:
             return QVariant(QDateTime::fromTime_t( c->phoneNumbers().lastUsedTimeStamp()));
-         case ContactModel::Role::Filter: {
-            //Strip non essential characters like accents from the filter string
-            QString normStripppedC;
-            foreach(QChar char2,QString(c->formattedName()+'\n'+c->organization()+'\n'+c->group()+'\n'+
-               c->department()+'\n'+c->preferredEmail()).toLower().normalized(QString::NormalizationForm_KD) ) {
-               if (!char2.combiningClass())
-                  normStripppedC += char2;
-            }
-            return normStripppedC;
-         }
+         case ContactModel::Role::Filter:
+            return c->filterString();
          default:
             break;
       }