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 <[email protected]> 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