You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Ray Chen <cl...@gmail.com> on 2010/07/22 07:07:25 UTC

Security Performance issue

Hi All,
I found that our security implementation is much slower than RI's when
get an algorithm instance.
I have done some investigation and found that most time are consumed
on loading and initialising providers.
Following is the test cases and results to show this problem.

                      RI5         |      RI6      |     Harmony5    |
  Harmony6
Testcase1[1]    78ms      | 90~100ms  |     450ms        |   475~490ms
Testcase2[2]    75ms      |  85~91ms  |                       |
Testcase3[3]                  |                 |   447~455ms    | 470~490ms
Testcase4[4]    9~10ms  |   6ms         |                       |
Testcase5[5]                 |                  |    448~462ms   |  479~501ms
Testcase6[6]    9ms       |    8~10ms   |   448~459ms   |   481~490ms

From[1], we can see our implementation is much slower than RI's when
loading all the providers.
Compare [2] & [3], both loading JSSE provider, our implementation is
much slower.
Compare [2] & [4], the time differs, which means RI can load providers
one by one.
Compare [1],[3] & [5], we can see our implementation consumes almost
same time whether it loads one or more providers.
Form[6], I guess RI knows what services a provider provides so that it
can just pick up the providers the application need.

If you look into the Services.java, you will find that our
implementation will load all the providers when this class is loaded
even this application does NOT need some of providers.
Then it put all the providers and services into a cache which can be
called "pre-loading".

Base on the above investigation, I suggest to change the "pre-loading"
to "lazy-loading" if possible which means only loading necessary
providers, no more, no less.

But I found that it is very hard to achieve this target, because we
don't know what services a provider provides before we load the
provider.
I don't know what RI does to achieve this.
Maybe we can store the map relationships between these default
providers and services to a file or internal cache table?

Any comments or suggestions?

Jimmy, Kevin,
I talked to you about this issue before, feel free to fix me if
anything is wrong.
Or you can give more information about this issue.

[1]
public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (Provider p : Security.getProviders()) {
            p.getServices();
        }
        System.out.println(System.currentTimeMillis() - start);
}

[2]
public static void main(String[] args) throws NoSuchAlgorithmException {
    long start = System.currentTimeMillis();
    Security.getProvider("SUNJSSE");
    System.out.println(System.currentTimeMillis() - start);
}

[3]
public static void main(String[] args) throws NoSuchAlgorithmException {
     long start = System.currentTimeMillis();
     Security.getProvider("HarmonyJSSE");
     System.out.println(System.currentTimeMillis() - start);
}

[4]
public static void main(String[] args) throws NoSuchAlgorithmException {
        long start = System.currentTimeMillis();
        Security.getProvider("SUN");
        System.out.println(System.currentTimeMillis() - start);
}

[5]
public static void main(String[] args) throws NoSuchAlgorithmException {
    long start = System.currentTimeMillis();
    Security.getProvider("BC");
    System.out.println(System.currentTimeMillis() - start);
}

[6]
public static void main(String[] args) throws NoSuchAlgorithmException {
    long start = System.currentTimeMillis();
    MessageDigest.getInstance("SHA-1");
    System.out.println(System.currentTimeMillis() - start);
}
-- 
Regards,

Ray Chen

Re: Security Performance issue

Posted by Tim Ellison <t....@gmail.com>.
On 22/Jul/2010 06:07, Ray Chen wrote:
> Hi All,
> I found that our security implementation is much slower than RI's when
> get an algorithm instance.
> I have done some investigation and found that most time are consumed
> on loading and initialising providers.
> Following is the test cases and results to show this problem.
> 
>                       RI5         |      RI6      |     Harmony5    |
>   Harmony6
> Testcase1[1]    78ms      | 90~100ms  |     450ms        |   475~490ms
> Testcase2[2]    75ms      |  85~91ms  |                       |
> Testcase3[3]                  |                 |   447~455ms    | 470~490ms
> Testcase4[4]    9~10ms  |   6ms         |                       |
> Testcase5[5]                 |                  |    448~462ms   |  479~501ms
> Testcase6[6]    9ms       |    8~10ms   |   448~459ms   |   481~490ms
> 
> From[1], we can see our implementation is much slower than RI's when
> loading all the providers.
> Compare [2] & [3], both loading JSSE provider, our implementation is
> much slower.
> Compare [2] & [4], the time differs, which means RI can load providers
> one by one.
> Compare [1],[3] & [5], we can see our implementation consumes almost
> same time whether it loads one or more providers.
> Form[6], I guess RI knows what services a provider provides so that it
> can just pick up the providers the application need.
> 
> If you look into the Services.java, you will find that our
> implementation will load all the providers when this class is loaded
> even this application does NOT need some of providers.
> Then it put all the providers and services into a cache which can be
> called "pre-loading".
> 
> Base on the above investigation, I suggest to change the "pre-loading"
> to "lazy-loading" if possible which means only loading necessary
> providers, no more, no less.
> 
> But I found that it is very hard to achieve this target, because we
> don't know what services a provider provides before we load the
> provider.

Do we need to know which services a provider offers before the service
is requested?  We could be lazy and leave the load and search of the
providers class until a service is requested.

So rather than load all the providers in the static initializer of
Services, we simply read in the names of the providers during
initialization, then start to load them, in order, when
getProvider(name)/getService(key) is called, and stop loading more when
the name is satisfied?

I realize it will need some playing around to maintain a list of 'not
yet loaded providers' -- and if the typical use case is a call to
getProviders() then it won't help because all will end up being loaded.

Regards,
Tim

> I don't know what RI does to achieve this.
> Maybe we can store the map relationships between these default
> providers and services to a file or internal cache table?
> 
> Any comments or suggestions?
> 
> Jimmy, Kevin,
> I talked to you about this issue before, feel free to fix me if
> anything is wrong.
> Or you can give more information about this issue.
> 
> [1]
> public static void main(String[] args) {
>         long start = System.currentTimeMillis();
>         for (Provider p : Security.getProviders()) {
>             p.getServices();
>         }
>         System.out.println(System.currentTimeMillis() - start);
> }
> 
> [2]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>     long start = System.currentTimeMillis();
>     Security.getProvider("SUNJSSE");
>     System.out.println(System.currentTimeMillis() - start);
> }
> 
> [3]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>      long start = System.currentTimeMillis();
>      Security.getProvider("HarmonyJSSE");
>      System.out.println(System.currentTimeMillis() - start);
> }
> 
> [4]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>         long start = System.currentTimeMillis();
>         Security.getProvider("SUN");
>         System.out.println(System.currentTimeMillis() - start);
> }
> 
> [5]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>     long start = System.currentTimeMillis();
>     Security.getProvider("BC");
>     System.out.println(System.currentTimeMillis() - start);
> }
> 
> [6]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>     long start = System.currentTimeMillis();
>     MessageDigest.getInstance("SHA-1");
>     System.out.println(System.currentTimeMillis() - start);
> }

Re: Security Performance issue

Posted by Deven You <de...@gmail.com>.
I am not sure which classes are loaded during the Security.getProvider() for
both harmony and RI, and I found another interesting thing that is  the time
spent on Class.newInstance() on both harmony and RI are almost the same
though the time on the Class.forName() are different so much.

2010/7/24 Deven You <de...@gmail.com>

> Hi Tim
> Actually I mean Class.forName() in theSecurity.getProvider() invocation
> stack. So I can be sure our security implementation loads much more classes
> than RI's one. Thanks for your question, I think on the above mail I talked
> so generally.
>
> 2010/7/24 Tim Ellison <t....@gmail.com>
>
> On 22/Jul/2010 11:42, Deven You wrote:
>> > Profiling results show RI's Class.forName() takes much less time than
>> > Harmony ones. It may caused by harmony load too much classes, maybe we
>> need
>> > consider load providers only needed.
>>
>> You mean "Class.forName()" loading the same class (i.e. the time to
>> search and load a given class), or are you talking about the load/init
>> time for BouncyCastle's providers compared to the RI providers?
>>
>> Regards,
>> Tim
>>
>> > 2010/7/22 Regis <xu...@gmail.com>
>> >
>> >> On 2010-07-22 14:26, Ray Chen wrote:
>> >>
>> >>> Hi Regis,
>> >>> You mean init these providers is slow, right? But actually we should
>> >>> not init unnecessary providers.
>> >>>
>> >>> I added some info in our code as following and you can see init these
>> >>> provider takes most of the time:
>> >>> <code>
>> >>> ...
>> >>> long start = System.currentTimeMillis();
>> >>> p = (Provider) Class.forName(providerClassName.trim(), true,
>> >>> cl).newInstance();
>> >>> System.out.println("init " + p.getName() + "takes " +
>> >>> (System.currentTimeMillis()-start) + " ms");
>> >>> providers.add(p);
>> >>> providersNames.put(p.getName(), p);
>> >>> long start2 = System.currentTimeMillis();
>> >>> initServiceInfo(p);
>> >>> System.out.println("init services of " + p.getName() + "takes " +
>> >>> (System.currentTimeMillis() - start2) + " ms" );
>> >>> ...
>> >>> </code>
>> >>>
>> >>> And the output is:
>> >>> init DRLCertFactorytakes 226 ms
>> >>> init services of DRLCertFactorytakes 6 ms
>> >>> init Cryptotakes 1 ms
>> >>> init services of Cryptotakes 1 ms
>> >>> init HarmonyJSSEtakes 0 ms
>> >>> init services of HarmonyJSSEtakes 1 ms
>> >>> init BCtakes 204 ms
>> >>> init services of BCtakes 11 ms
>> >>>
>> >>>
>> >>> On Thu, Jul 22, 2010 at 2:01 PM, Regis<xu...@gmail.com>  wrote:
>> >>>
>> >> init DRLCertFactorytakes 226 ms
>> >> init BCtakes 204 ms
>> >>
>> >> It seems provider itself spent a lot of time.
>> >>
>> >> Have you compared time of following code against RI and Harmony with
>> the
>> >> same provider class name?
>> >>
>> >>
>> >> (Provider) Class.forName(providerClassName.trim(), true,
>> cl).newInstance();
>> >>
>> >> If there were still huge gaps, I think it's not caused by way we load
>> >> providers, maybe there are other performance hole in some places. I
>> agree
>> >> that the way loading providers still have room to improve, but we need
>> to
>> >> find out and shoot the most outstanding issue first.
>> >>
>> >>
>> >>
>> >> --
>> >> Best Regards,
>> >> Regis.
>> >>
>> >
>>
>
>

Re: Security Performance issue

Posted by Deven You <de...@gmail.com>.
Hi Tim
Actually I mean Class.forName() in theSecurity.getProvider() invocation
stack. So I can be sure our security implementation loads much more classes
than RI's one. Thanks for your question, I think on the above mail I talked
so generally.

2010/7/24 Tim Ellison <t....@gmail.com>

> On 22/Jul/2010 11:42, Deven You wrote:
> > Profiling results show RI's Class.forName() takes much less time than
> > Harmony ones. It may caused by harmony load too much classes, maybe we
> need
> > consider load providers only needed.
>
> You mean "Class.forName()" loading the same class (i.e. the time to
> search and load a given class), or are you talking about the load/init
> time for BouncyCastle's providers compared to the RI providers?
>
> Regards,
> Tim
>
> > 2010/7/22 Regis <xu...@gmail.com>
> >
> >> On 2010-07-22 14:26, Ray Chen wrote:
> >>
> >>> Hi Regis,
> >>> You mean init these providers is slow, right? But actually we should
> >>> not init unnecessary providers.
> >>>
> >>> I added some info in our code as following and you can see init these
> >>> provider takes most of the time:
> >>> <code>
> >>> ...
> >>> long start = System.currentTimeMillis();
> >>> p = (Provider) Class.forName(providerClassName.trim(), true,
> >>> cl).newInstance();
> >>> System.out.println("init " + p.getName() + "takes " +
> >>> (System.currentTimeMillis()-start) + " ms");
> >>> providers.add(p);
> >>> providersNames.put(p.getName(), p);
> >>> long start2 = System.currentTimeMillis();
> >>> initServiceInfo(p);
> >>> System.out.println("init services of " + p.getName() + "takes " +
> >>> (System.currentTimeMillis() - start2) + " ms" );
> >>> ...
> >>> </code>
> >>>
> >>> And the output is:
> >>> init DRLCertFactorytakes 226 ms
> >>> init services of DRLCertFactorytakes 6 ms
> >>> init Cryptotakes 1 ms
> >>> init services of Cryptotakes 1 ms
> >>> init HarmonyJSSEtakes 0 ms
> >>> init services of HarmonyJSSEtakes 1 ms
> >>> init BCtakes 204 ms
> >>> init services of BCtakes 11 ms
> >>>
> >>>
> >>> On Thu, Jul 22, 2010 at 2:01 PM, Regis<xu...@gmail.com>  wrote:
> >>>
> >> init DRLCertFactorytakes 226 ms
> >> init BCtakes 204 ms
> >>
> >> It seems provider itself spent a lot of time.
> >>
> >> Have you compared time of following code against RI and Harmony with the
> >> same provider class name?
> >>
> >>
> >> (Provider) Class.forName(providerClassName.trim(), true,
> cl).newInstance();
> >>
> >> If there were still huge gaps, I think it's not caused by way we load
> >> providers, maybe there are other performance hole in some places. I
> agree
> >> that the way loading providers still have room to improve, but we need
> to
> >> find out and shoot the most outstanding issue first.
> >>
> >>
> >>
> >> --
> >> Best Regards,
> >> Regis.
> >>
> >
>

Re: Security Performance issue

Posted by Tim Ellison <t....@gmail.com>.
On 22/Jul/2010 11:42, Deven You wrote:
> Profiling results show RI's Class.forName() takes much less time than
> Harmony ones. It may caused by harmony load too much classes, maybe we need
> consider load providers only needed.

You mean "Class.forName()" loading the same class (i.e. the time to
search and load a given class), or are you talking about the load/init
time for BouncyCastle's providers compared to the RI providers?

Regards,
Tim

> 2010/7/22 Regis <xu...@gmail.com>
> 
>> On 2010-07-22 14:26, Ray Chen wrote:
>>
>>> Hi Regis,
>>> You mean init these providers is slow, right? But actually we should
>>> not init unnecessary providers.
>>>
>>> I added some info in our code as following and you can see init these
>>> provider takes most of the time:
>>> <code>
>>> ...
>>> long start = System.currentTimeMillis();
>>> p = (Provider) Class.forName(providerClassName.trim(), true,
>>> cl).newInstance();
>>> System.out.println("init " + p.getName() + "takes " +
>>> (System.currentTimeMillis()-start) + " ms");
>>> providers.add(p);
>>> providersNames.put(p.getName(), p);
>>> long start2 = System.currentTimeMillis();
>>> initServiceInfo(p);
>>> System.out.println("init services of " + p.getName() + "takes " +
>>> (System.currentTimeMillis() - start2) + " ms" );
>>> ...
>>> </code>
>>>
>>> And the output is:
>>> init DRLCertFactorytakes 226 ms
>>> init services of DRLCertFactorytakes 6 ms
>>> init Cryptotakes 1 ms
>>> init services of Cryptotakes 1 ms
>>> init HarmonyJSSEtakes 0 ms
>>> init services of HarmonyJSSEtakes 1 ms
>>> init BCtakes 204 ms
>>> init services of BCtakes 11 ms
>>>
>>>
>>> On Thu, Jul 22, 2010 at 2:01 PM, Regis<xu...@gmail.com>  wrote:
>>>
>> init DRLCertFactorytakes 226 ms
>> init BCtakes 204 ms
>>
>> It seems provider itself spent a lot of time.
>>
>> Have you compared time of following code against RI and Harmony with the
>> same provider class name?
>>
>>
>> (Provider) Class.forName(providerClassName.trim(), true, cl).newInstance();
>>
>> If there were still huge gaps, I think it's not caused by way we load
>> providers, maybe there are other performance hole in some places. I agree
>> that the way loading providers still have room to improve, but we need to
>> find out and shoot the most outstanding issue first.
>>
>>
>>
>> --
>> Best Regards,
>> Regis.
>>
> 

Re: Security Performance issue

Posted by Deven You <de...@gmail.com>.
Profiling results show RI's Class.forName() takes much less time than
Harmony ones. It may caused by harmony load too much classes, maybe we need
consider load providers only needed.

2010/7/22 Regis <xu...@gmail.com>

> On 2010-07-22 14:26, Ray Chen wrote:
>
>> Hi Regis,
>> You mean init these providers is slow, right? But actually we should
>> not init unnecessary providers.
>>
>> I added some info in our code as following and you can see init these
>> provider takes most of the time:
>> <code>
>> ...
>> long start = System.currentTimeMillis();
>> p = (Provider) Class.forName(providerClassName.trim(), true,
>> cl).newInstance();
>> System.out.println("init " + p.getName() + "takes " +
>> (System.currentTimeMillis()-start) + " ms");
>> providers.add(p);
>> providersNames.put(p.getName(), p);
>> long start2 = System.currentTimeMillis();
>> initServiceInfo(p);
>> System.out.println("init services of " + p.getName() + "takes " +
>> (System.currentTimeMillis() - start2) + " ms" );
>> ...
>> </code>
>>
>> And the output is:
>> init DRLCertFactorytakes 226 ms
>> init services of DRLCertFactorytakes 6 ms
>> init Cryptotakes 1 ms
>> init services of Cryptotakes 1 ms
>> init HarmonyJSSEtakes 0 ms
>> init services of HarmonyJSSEtakes 1 ms
>> init BCtakes 204 ms
>> init services of BCtakes 11 ms
>>
>>
>> On Thu, Jul 22, 2010 at 2:01 PM, Regis<xu...@gmail.com>  wrote:
>>
>
> init DRLCertFactorytakes 226 ms
> init BCtakes 204 ms
>
> It seems provider itself spent a lot of time.
>
> Have you compared time of following code against RI and Harmony with the
> same provider class name?
>
>
> (Provider) Class.forName(providerClassName.trim(), true, cl).newInstance();
>
> If there were still huge gaps, I think it's not caused by way we load
> providers, maybe there are other performance hole in some places. I agree
> that the way loading providers still have room to improve, but we need to
> find out and shoot the most outstanding issue first.
>
>
>
> --
> Best Regards,
> Regis.
>

Re: Security Performance issue

Posted by Regis <xu...@gmail.com>.
On 2010-07-22 14:26, Ray Chen wrote:
> Hi Regis,
> You mean init these providers is slow, right? But actually we should
> not init unnecessary providers.
>
> I added some info in our code as following and you can see init these
> provider takes most of the time:
> <code>
> ...
> long start = System.currentTimeMillis();
> p = (Provider) Class.forName(providerClassName.trim(), true, cl).newInstance();
> System.out.println("init " + p.getName() + "takes " +
> (System.currentTimeMillis()-start) + " ms");
> providers.add(p);
> providersNames.put(p.getName(), p);
> long start2 = System.currentTimeMillis();
> initServiceInfo(p);
> System.out.println("init services of " + p.getName() + "takes " +
> (System.currentTimeMillis() - start2) + " ms" );
> ...
> </code>
>
> And the output is:
> init DRLCertFactorytakes 226 ms
> init services of DRLCertFactorytakes 6 ms
> init Cryptotakes 1 ms
> init services of Cryptotakes 1 ms
> init HarmonyJSSEtakes 0 ms
> init services of HarmonyJSSEtakes 1 ms
> init BCtakes 204 ms
> init services of BCtakes 11 ms
>
>
> On Thu, Jul 22, 2010 at 2:01 PM, Regis<xu...@gmail.com>  wrote:

init DRLCertFactorytakes 226 ms
init BCtakes 204 ms

It seems provider itself spent a lot of time.

Have you compared time of following code against RI and Harmony with the same 
provider class name?

(Provider) Class.forName(providerClassName.trim(), true, cl).newInstance();

If there were still huge gaps, I think it's not caused by way we load providers, 
maybe there are other performance hole in some places. I agree that the way 
loading providers still have room to improve, but we need to find out and shoot 
the most outstanding issue first.



-- 
Best Regards,
Regis.

Re: Security Performance issue

Posted by Ray Chen <cl...@gmail.com>.
Hi Regis,
You mean init these providers is slow, right? But actually we should
not init unnecessary providers.

I added some info in our code as following and you can see init these
provider takes most of the time:
<code>
...
long start = System.currentTimeMillis();
p = (Provider) Class.forName(providerClassName.trim(), true, cl).newInstance();
System.out.println("init " + p.getName() + "takes " +
(System.currentTimeMillis()-start) + " ms");
providers.add(p);
providersNames.put(p.getName(), p);
long start2 = System.currentTimeMillis();
initServiceInfo(p);
System.out.println("init services of " + p.getName() + "takes " +
(System.currentTimeMillis() - start2) + " ms" );
...
</code>

And the output is:
init DRLCertFactorytakes 226 ms
init services of DRLCertFactorytakes 6 ms
init Cryptotakes 1 ms
init services of Cryptotakes 1 ms
init HarmonyJSSEtakes 0 ms
init services of HarmonyJSSEtakes 1 ms
init BCtakes 204 ms
init services of BCtakes 11 ms


On Thu, Jul 22, 2010 at 2:01 PM, Regis <xu...@gmail.com> wrote:
> On 2010-07-22 13:07, Ray Chen wrote:
>>
>> Hi All,
>> I found that our security implementation is much slower than RI's when
>> get an algorithm instance.
>> I have done some investigation and found that most time are consumed
>> on loading and initialising providers.
>> Following is the test cases and results to show this problem.
>>
>>                       RI5         |      RI6      |     Harmony5    |
>>   Harmony6
>> Testcase1[1]    78ms      | 90~100ms  |     450ms        |   475~490ms
>> Testcase2[2]    75ms      |  85~91ms  |                       |
>> Testcase3[3]                  |                 |   447~455ms    |
>> 470~490ms
>> Testcase4[4]    9~10ms  |   6ms         |                       |
>> Testcase5[5]                 |                  |    448~462ms   |
>>  479~501ms
>> Testcase6[6]    9ms       |    8~10ms   |   448~459ms   |   481~490ms
>>
>> From[1], we can see our implementation is much slower than RI's when
>> loading all the providers.
>> Compare [2]&  [3], both loading JSSE provider, our implementation is
>> much slower.
>> Compare [2]&  [4], the time differs, which means RI can load providers
>> one by one.
>> Compare [1],[3]&  [5], we can see our implementation consumes almost
>> same time whether it loads one or more providers.
>> Form[6], I guess RI knows what services a provider provides so that it
>> can just pick up the providers the application need.
>>
>> If you look into the Services.java, you will find that our
>> implementation will load all the providers when this class is loaded
>> even this application does NOT need some of providers.
>> Then it put all the providers and services into a cache which can be
>> called "pre-loading".
>>
>> Base on the above investigation, I suggest to change the "pre-loading"
>> to "lazy-loading" if possible which means only loading necessary
>> providers, no more, no less.
>>
>> But I found that it is very hard to achieve this target, because we
>> don't know what services a provider provides before we load the
>> provider.
>> I don't know what RI does to achieve this.
>> Maybe we can store the map relationships between these default
>> providers and services to a file or internal cache table?
>>
>> Any comments or suggestions?
>>
>> Jimmy, Kevin,
>> I talked to you about this issue before, feel free to fix me if
>> anything is wrong.
>> Or you can give more information about this issue.
>>
>> [1]
>> public static void main(String[] args) {
>>         long start = System.currentTimeMillis();
>>         for (Provider p : Security.getProviders()) {
>>             p.getServices();
>>         }
>>         System.out.println(System.currentTimeMillis() - start);
>> }
>>
>> [2]
>> public static void main(String[] args) throws NoSuchAlgorithmException {
>>     long start = System.currentTimeMillis();
>>     Security.getProvider("SUNJSSE");
>>     System.out.println(System.currentTimeMillis() - start);
>> }
>>
>> [3]
>> public static void main(String[] args) throws NoSuchAlgorithmException {
>>      long start = System.currentTimeMillis();
>>      Security.getProvider("HarmonyJSSE");
>>      System.out.println(System.currentTimeMillis() - start);
>> }
>>
>> [4]
>> public static void main(String[] args) throws NoSuchAlgorithmException {
>>         long start = System.currentTimeMillis();
>>         Security.getProvider("SUN");
>>         System.out.println(System.currentTimeMillis() - start);
>> }
>>
>> [5]
>> public static void main(String[] args) throws NoSuchAlgorithmException {
>>     long start = System.currentTimeMillis();
>>     Security.getProvider("BC");
>>     System.out.println(System.currentTimeMillis() - start);
>> }
>>
>> [6]
>> public static void main(String[] args) throws NoSuchAlgorithmException {
>>     long start = System.currentTimeMillis();
>>     MessageDigest.getInstance("SHA-1");
>>     System.out.println(System.currentTimeMillis() - start);
>> }
>
> "Security.getProvider" at least has two steps: searching providers and
> initializing providers. Searching providers is implemented by Harmony,
> initializing is implemented by providers, from your test and data, we don't
> know which part is performance killer.
>
> And BouncyCastle supports a lots of algorithms, I'm not sure if it support
> lazy loading.
>
> --
> Best Regards,
> Regis.
>



-- 
Regards,

Ray Chen

Re: Security Performance issue

Posted by Regis <xu...@gmail.com>.
On 2010-07-22 13:07, Ray Chen wrote:
> Hi All,
> I found that our security implementation is much slower than RI's when
> get an algorithm instance.
> I have done some investigation and found that most time are consumed
> on loading and initialising providers.
> Following is the test cases and results to show this problem.
>
>                        RI5         |      RI6      |     Harmony5    |
>    Harmony6
> Testcase1[1]    78ms      | 90~100ms  |     450ms        |   475~490ms
> Testcase2[2]    75ms      |  85~91ms  |                       |
> Testcase3[3]                  |                 |   447~455ms    | 470~490ms
> Testcase4[4]    9~10ms  |   6ms         |                       |
> Testcase5[5]                 |                  |    448~462ms   |  479~501ms
> Testcase6[6]    9ms       |    8~10ms   |   448~459ms   |   481~490ms
>
> From[1], we can see our implementation is much slower than RI's when
> loading all the providers.
> Compare [2]&  [3], both loading JSSE provider, our implementation is
> much slower.
> Compare [2]&  [4], the time differs, which means RI can load providers
> one by one.
> Compare [1],[3]&  [5], we can see our implementation consumes almost
> same time whether it loads one or more providers.
> Form[6], I guess RI knows what services a provider provides so that it
> can just pick up the providers the application need.
>
> If you look into the Services.java, you will find that our
> implementation will load all the providers when this class is loaded
> even this application does NOT need some of providers.
> Then it put all the providers and services into a cache which can be
> called "pre-loading".
>
> Base on the above investigation, I suggest to change the "pre-loading"
> to "lazy-loading" if possible which means only loading necessary
> providers, no more, no less.
>
> But I found that it is very hard to achieve this target, because we
> don't know what services a provider provides before we load the
> provider.
> I don't know what RI does to achieve this.
> Maybe we can store the map relationships between these default
> providers and services to a file or internal cache table?
>
> Any comments or suggestions?
>
> Jimmy, Kevin,
> I talked to you about this issue before, feel free to fix me if
> anything is wrong.
> Or you can give more information about this issue.
>
> [1]
> public static void main(String[] args) {
>          long start = System.currentTimeMillis();
>          for (Provider p : Security.getProviders()) {
>              p.getServices();
>          }
>          System.out.println(System.currentTimeMillis() - start);
> }
>
> [2]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>      long start = System.currentTimeMillis();
>      Security.getProvider("SUNJSSE");
>      System.out.println(System.currentTimeMillis() - start);
> }
>
> [3]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>       long start = System.currentTimeMillis();
>       Security.getProvider("HarmonyJSSE");
>       System.out.println(System.currentTimeMillis() - start);
> }
>
> [4]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>          long start = System.currentTimeMillis();
>          Security.getProvider("SUN");
>          System.out.println(System.currentTimeMillis() - start);
> }
>
> [5]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>      long start = System.currentTimeMillis();
>      Security.getProvider("BC");
>      System.out.println(System.currentTimeMillis() - start);
> }
>
> [6]
> public static void main(String[] args) throws NoSuchAlgorithmException {
>      long start = System.currentTimeMillis();
>      MessageDigest.getInstance("SHA-1");
>      System.out.println(System.currentTimeMillis() - start);
> }

"Security.getProvider" at least has two steps: searching providers and 
initializing providers. Searching providers is implemented by Harmony, 
initializing is implemented by providers, from your test and data, we don't know 
which part is performance killer.

And BouncyCastle supports a lots of algorithms, I'm not sure if it support lazy 
loading.

-- 
Best Regards,
Regis.