summaryrefslogtreecommitdiffstats
path: root/third_party/libphonenumber
diff options
context:
space:
mode:
authorgeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 16:49:17 +0000
committergeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 16:49:17 +0000
commit768e7871ff550ca23ab0ff7f400bfd9edc5b57ee (patch)
tree29b81abdf2f98b7c08219c064f54d6da1dc81cea /third_party/libphonenumber
parente7427721b4014dd0fbbdfc75372b50791f9e6ad8 (diff)
downloadchromium_src-768e7871ff550ca23ab0ff7f400bfd9edc5b57ee.zip
chromium_src-768e7871ff550ca23ab0ff7f400bfd9edc5b57ee.tar.gz
chromium_src-768e7871ff550ca23ab0ff7f400bfd9edc5b57ee.tar.bz2
Improved performance on some phone-related functions by 8x (1251ms on average against 9773.4ms on average on
AutofillManagerTest.DeterminePossibleFieldTypesForUpload with 100 profiles). Real life performance improvement should be even bigger as most phones will be parsed once. TEST=The caching object is tested by multiple AutofillManager, PersonalDataManager, etc. unittests + new unit-test to test performance. BUG=85152 Review URL: http://codereview.chromium.org/7134032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89016 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/libphonenumber')
-rw-r--r--third_party/libphonenumber/chrome/regexp_adapter_icuregexp.cc66
-rw-r--r--third_party/libphonenumber/cpp/src/phonenumberutil.cc40
-rw-r--r--third_party/libphonenumber/cpp/src/phonenumberutil.h5
3 files changed, 70 insertions, 41 deletions
diff --git a/third_party/libphonenumber/chrome/regexp_adapter_icuregexp.cc b/third_party/libphonenumber/chrome/regexp_adapter_icuregexp.cc
index 6b6ad82..d4972ce 100644
--- a/third_party/libphonenumber/chrome/regexp_adapter_icuregexp.cc
+++ b/third_party/libphonenumber/chrome/regexp_adapter_icuregexp.cc
@@ -4,8 +4,11 @@
#include "third_party/libphonenumber/cpp/src/regexp_adapter.h"
+#include <map>
+
// Setup all of the Chromium and WebKit defines
#include "base/logging.h"
+#include "base/memory/singleton.h"
#include "base/scoped_ptr.h"
#include "build/build_config.h"
#include "unicode/regex.h"
@@ -103,11 +106,44 @@ class IcuRegularExpression : public reg_exp::RegularExpression {
bool global,
const char* replacement_string) const;
private:
- scoped_ptr<icu::RegexPattern> utf8_regexp_;
+ icu::RegexPattern utf8_regexp_;
DISALLOW_COPY_AND_ASSIGN(IcuRegularExpression);
};
+class RegExpCache {
+ public:
+ static RegExpCache* GetInstance();
+ const icu::RegexPattern& GetRegExp(const std::string& reg_exp);
+
+ private:
+ std::map<std::string, icu::RegexPattern> reg_exp_cache_;
+ icu::RegexPattern empty_regexp_;
+};
+
+RegExpCache* RegExpCache::GetInstance() {
+ return Singleton<RegExpCache>::get();
+}
+
+const icu::RegexPattern& RegExpCache::GetRegExp(const std::string& reg_exp) {
+ std::map<std::string, icu::RegexPattern>::iterator it =
+ reg_exp_cache_.find(reg_exp);
+ UParseError pe;
+ UErrorCode status = U_ZERO_ERROR;
+ if (it == reg_exp_cache_.end()) {
+ scoped_ptr<icu::RegexPattern> pattern(icu::RegexPattern::compile(
+ icu::UnicodeString::fromUTF8(reg_exp), 0, pe, status));
+ if (U_SUCCESS(status)) {
+ it = reg_exp_cache_.insert(std::make_pair(reg_exp, *pattern)).first;
+ } else {
+ // All of the passed regular expressions should compile correctly.
+ NOTREACHED();
+ return empty_regexp_;
+ }
+ }
+ return it->second;
+}
+
IcuRegularExpressionInput::IcuRegularExpressionInput(const char* utf8_input)
: pos_(0) {
DCHECK(utf8_input);
@@ -132,15 +168,8 @@ std::string IcuRegularExpressionInput::ToString() const {
IcuRegularExpression::IcuRegularExpression(const char* utf8_regexp) {
DCHECK(utf8_regexp);
- UParseError pe;
- UErrorCode status = U_ZERO_ERROR;
- utf8_regexp_.reset(icu::RegexPattern::compile(
- icu::UnicodeString::fromUTF8(utf8_regexp), 0, pe, status));
- if (U_FAILURE(status)) {
- // All of the passed regular expressions should compile correctly.
- utf8_regexp_.reset(NULL);
- NOTREACHED();
- }
+ std::string regexp_key(utf8_regexp);
+ utf8_regexp_ = RegExpCache::GetInstance()->GetRegExp(regexp_key);
}
bool IcuRegularExpression::Consume(
@@ -153,14 +182,11 @@ bool IcuRegularExpression::Consume(
// matched_string1 may be NULL
// matched_string2 may be NULL
// matched_string3 may be NULL
- if (!utf8_regexp_.get())
- return false;
-
IcuRegularExpressionInput* input =
reinterpret_cast<IcuRegularExpressionInput *>(input_string);
UErrorCode status = U_ZERO_ERROR;
- scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_->matcher(*(input->Data()),
- status));
+ scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_.matcher(*(input->Data()),
+ status));
if (U_FAILURE(status))
return false;
@@ -198,13 +224,11 @@ bool IcuRegularExpression::Match(const char* input_string,
std::string* matched_string) const {
DCHECK(input_string);
// matched_string may be NULL
- if (!utf8_regexp_.get())
- return false;
IcuRegularExpressionInput input(input_string);
UErrorCode status = U_ZERO_ERROR;
- scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_->matcher(*(input.Data()),
- status));
+ scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_.matcher(*(input.Data()),
+ status));
if (U_FAILURE(status))
return false;
@@ -264,8 +288,8 @@ bool IcuRegularExpression::Replace(std::string* string_to_process,
IcuRegularExpressionInput input(string_to_process->c_str());
UErrorCode status = U_ZERO_ERROR;
- scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_->matcher(*(input.Data()),
- status));
+ scoped_ptr<icu::RegexMatcher> matcher(utf8_regexp_.matcher(*(input.Data()),
+ status));
if (U_FAILURE(status))
return false;
diff --git a/third_party/libphonenumber/cpp/src/phonenumberutil.cc b/third_party/libphonenumber/cpp/src/phonenumberutil.cc
index b0201f2..28fbd43 100644
--- a/third_party/libphonenumber/cpp/src/phonenumberutil.cc
+++ b/third_party/libphonenumber/cpp/src/phonenumberutil.cc
@@ -1765,30 +1765,32 @@ void PhoneNumberUtil::NormalizeDigitsOnly(string* number) {
UParseError error;
icu::ErrorCode status;
- scoped_ptr<icu::Transliterator> transliterator(
- icu::Transliterator::createFromRules(
- "NormalizeDecimalDigits",
- "[[:nv=0:]-[0]-[:^nt=de:]]>0;"
- "[[:nv=1:]-[1]-[:^nt=de:]]>1;"
- "[[:nv=2:]-[2]-[:^nt=de:]]>2;"
- "[[:nv=3:]-[3]-[:^nt=de:]]>3;"
- "[[:nv=4:]-[4]-[:^nt=de:]]>4;"
- "[[:nv=5:]-[5]-[:^nt=de:]]>5;"
- "[[:nv=6:]-[6]-[:^nt=de:]]>6;"
- "[[:nv=7:]-[7]-[:^nt=de:]]>7;"
- "[[:nv=8:]-[8]-[:^nt=de:]]>8;"
- "[[:nv=9:]-[9]-[:^nt=de:]]>9;",
- UTRANS_FORWARD,
- error,
- status
- )
- );
+ if (!GetInstance()->transliterator_.get()) {
+ GetInstance()->transliterator_.reset(
+ icu::Transliterator::createFromRules(
+ "NormalizeDecimalDigits",
+ "[[:nv=0:]-[0]-[:^nt=de:]]>0;"
+ "[[:nv=1:]-[1]-[:^nt=de:]]>1;"
+ "[[:nv=2:]-[2]-[:^nt=de:]]>2;"
+ "[[:nv=3:]-[3]-[:^nt=de:]]>3;"
+ "[[:nv=4:]-[4]-[:^nt=de:]]>4;"
+ "[[:nv=5:]-[5]-[:^nt=de:]]>5;"
+ "[[:nv=6:]-[6]-[:^nt=de:]]>6;"
+ "[[:nv=7:]-[7]-[:^nt=de:]]>7;"
+ "[[:nv=8:]-[8]-[:^nt=de:]]>8;"
+ "[[:nv=9:]-[9]-[:^nt=de:]]>9;",
+ UTRANS_FORWARD,
+ error,
+ status
+ )
+ );
+ }
if (!status.isSuccess()) {
logger->Error("Error creating ICU Transliterator");
return;
}
icu::UnicodeString utf16(icu::UnicodeString::fromUTF8(number->c_str()));
- transliterator->transliterate(utf16);
+ GetInstance()->transliterator_->transliterate(utf16);
number->clear();
utf16.toUTF8String(*number);
}
diff --git a/third_party/libphonenumber/cpp/src/phonenumberutil.h b/third_party/libphonenumber/cpp/src/phonenumberutil.h
index 6a766df..43137a0 100644
--- a/third_party/libphonenumber/cpp/src/phonenumberutil.h
+++ b/third_party/libphonenumber/cpp/src/phonenumberutil.h
@@ -26,6 +26,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <unicode/translit.h>
#include "base/scoped_ptr.h"
#include "base/singleton.h"
@@ -57,7 +58,7 @@ class PhoneNumberUtil {
public:
// INTERNATIONAL and NATIONAL formats are consistent with the definition
// in ITU-T Recommendation E. 123. For example, the number of the Google
- // Zürich office will be written as "+41 44 668 1800" in INTERNATIONAL
+ // Zurich office will be written as "+41 44 668 1800" in INTERNATIONAL
// format, and as "044 668 1800" in NATIONAL format. E164 format is as per
// INTERNATIONAL format but with no formatting applied e.g. +41446681800.
// RFC3966 is as per INTERNATIONAL format, but with all spaces and other
@@ -669,6 +670,8 @@ class PhoneNumberUtil {
bool check_region,
PhoneNumber* phone_number) const;
+ scoped_ptr<icu::Transliterator> transliterator_;
+
DISALLOW_COPY_AND_ASSIGN(PhoneNumberUtil);
};