-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fall back properly if chosen factory class isn't working. #28
Changes from 1 commit
6a41646
0eaa602
5a8073e
3124f92
9573540
932b706
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -266,8 +266,7 @@ public void run(Cipher cipher) throws Exception | |
private static CipherFactory benchmark( | ||
CipherFactory[] factories, | ||
int keySize, | ||
String transformation, | ||
boolean warmup | ||
String transformation | ||
) | ||
{ | ||
long minTime = Long.MAX_VALUE; | ||
|
@@ -282,6 +281,14 @@ private static CipherFactory benchmark( | |
if (factory == null) | ||
continue; | ||
|
||
// The user may have specified a specific CipherFactory class | ||
// (name) through setFactoryClassName(String), Practically, FACTORY_CLASS_NAME may override | ||
// minFactory and, consequently, it may appear that the benchmark is | ||
// unnecessary. Technically though, the specified CipherFactory may | ||
// malfunction. That is why FACTORY_CLASS_NAME is selected after it has | ||
// proven itself functional. | ||
boolean chosenFactoryClass = (factory.getClass().equals(Aes.factoryClass)); | ||
|
||
try | ||
{ | ||
Cipher cipher = factory.createCipher(transformation); | ||
|
@@ -295,18 +302,24 @@ private static CipherFactory benchmark( | |
} | ||
else | ||
{ | ||
/* If this is the user-chosen factory class, we don't really | ||
* need to benchmark it; just verify that it's working. | ||
*/ | ||
int numWarmups = chosenFactoryClass ? 0 : NUM_WARMUPS; | ||
int numBenchmarks = chosenFactoryClass ? 1 : NUM_BENCHMARKS; | ||
|
||
BenchmarkOperation benchmark = BenchmarkOperation.getBenchmark(transformation, keySize); | ||
if (warmup) | ||
if (!chosenFactoryClass) | ||
{ | ||
// Let the JVM "warm up" (do JIT compilation and the like) | ||
for (int i = 0; i < NUM_WARMUPS; i++) | ||
for (int i = 0; i < numWarmups; i++) | ||
{ | ||
benchmark.run(cipher); | ||
} | ||
} | ||
|
||
long startTime = System.nanoTime(); | ||
for (int i = 0; i < NUM_BENCHMARKS; i++) | ||
for (int i = 0; i < numBenchmarks; i++) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should line 329 use |
||
{ | ||
benchmark.run(cipher); | ||
} | ||
|
@@ -335,6 +348,19 @@ private static CipherFactory benchmark( | |
else if (t instanceof ThreadDeath) | ||
throw (ThreadDeath) t; | ||
} | ||
|
||
if (chosenFactoryClass) | ||
{ | ||
if (minFactory != null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand this well. If this loop iteration is for the user-configured factory class, return the fastest factory. If a previous non-user-configured factory was faster, we short-circuit and return it (the faster one)? Should that return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, elsewhere in the code I reorganize the list so the user-configured factory class is always first, so we avoid profiling factories we don't need to. But I agree that's fragile and confusing. I've reorganized it now, is it clearer? |
||
{ | ||
return minFactory; | ||
} | ||
else | ||
{ | ||
logger.warn("Chosen factory class \"" + FACTORY_CLASS_NAME + | ||
"\" not working for " + transformation); | ||
} | ||
} | ||
} | ||
|
||
if (log.length() != 0) | ||
|
@@ -537,26 +563,47 @@ else if (t instanceof ThreadDeath) | |
|
||
// If FACTORY_CLASS_NAME does not specify a well-known Class, add the | ||
// new Class to FACTORY_CLASSES. | ||
if (add && (factoryClass != null)) | ||
if (factoryClass != null) | ||
{ | ||
for (Class<?> clazz : factoryClasses) | ||
Class<?>[] newFactoryClasses; | ||
if (add) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think all of this is equivalent to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not quite - I want to put the new factory class first, whereas |
||
{ | ||
if (factoryClass.equals(clazz)) | ||
for (Class<?> clazz : factoryClasses) | ||
{ | ||
add = false; | ||
break; | ||
if (factoryClass.equals(clazz)) | ||
{ | ||
add = false; | ||
break; | ||
} | ||
} | ||
} | ||
if (add) | ||
{ | ||
Class<?>[] newFactoryClasses | ||
= new Class<?>[1 + factoryClasses.length]; | ||
if (add) | ||
{ | ||
newFactoryClasses | ||
= new Class<?>[1 + factoryClasses.length]; | ||
|
||
newFactoryClasses[0] = factoryClass; | ||
System.arraycopy( | ||
newFactoryClasses[0] = factoryClass; | ||
System.arraycopy( | ||
factoryClasses, 0, | ||
newFactoryClasses, 1, | ||
factoryClasses.length); | ||
} | ||
} | ||
else | ||
{ | ||
/* Otherwise, move the FACTORY_CLASS to the beginning of the list. */ | ||
newFactoryClasses | ||
= new Class<?>[factoryClasses.length]; | ||
|
||
newFactoryClasses[0] = factoryClass; | ||
int i = 1; | ||
for (Class<?> clazz : factoryClasses) | ||
{ | ||
if (!factoryClass.equals(clazz)) | ||
{ | ||
newFactoryClasses[i] = clazz; | ||
i++; | ||
} | ||
} | ||
factoryClasses = newFactoryClasses; | ||
} | ||
} | ||
|
@@ -639,30 +686,7 @@ private static CipherFactory getCipherFactory(String transformation, boolean war | |
// Benchmark the StreamCiphers provided by the available | ||
// StreamCipherFactories in order to select the fastest-performing | ||
// CipherFactory. | ||
CipherFactory minFactory = benchmark(factories, keySize, transformation, warmup); | ||
|
||
// The user may have specified a specific CipherFactory class | ||
// (name) through setFactoryClassName(String), Practically, FACTORY_CLASS_NAME may override | ||
// minFactory and, consequently, it may appear that the benchmark is | ||
// unnecessary. Technically though, the specified CipherFactory may | ||
// malfunction. That is why FACTORY_CLASS_NAME is selected after it has | ||
// proven itself functional. | ||
{ | ||
Class<? extends CipherFactory> factoryClass = Aes.factoryClass; | ||
|
||
if (factoryClass != null) | ||
{ | ||
for (CipherFactory factory : factories) | ||
{ | ||
if ((factory != null) | ||
&& factory.getClass().equals(factoryClass)) | ||
{ | ||
minFactory = factory; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
CipherFactory minFactory = benchmark(factories, keySize, transformation); | ||
|
||
return minFactory; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra parens on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, no, I reorganized this from an
if
statement.