diff options
author | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-14 16:49:17 +0000 |
---|---|---|
committer | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-14 16:49:17 +0000 |
commit | 768e7871ff550ca23ab0ff7f400bfd9edc5b57ee (patch) | |
tree | 29b81abdf2f98b7c08219c064f54d6da1dc81cea /third_party/libphonenumber | |
parent | e7427721b4014dd0fbbdfc75372b50791f9e6ad8 (diff) | |
download | chromium_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')
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); }; |