BQSR optimization: cache the BitSetUtils.bitSetFrom() calls since they are called over and over again with the same values. Another 10% reduction in runtime.

This commit is contained in:
Eric Banks 2012-06-08 13:54:37 -04:00
parent 898a0e6161
commit 92280b4068
2 changed files with 26 additions and 6 deletions

View File

@ -66,7 +66,7 @@ public class BQSRKeyManager {
for (Covariate optional : optionalCovariates) {
int nBits = optional.numberOfBits(); // number of bits used by this covariate
nOptionalBits = Math.max(nOptionalBits, nBits); // optional covariates are represented by the number of bits needed by biggest covariate
BitSet optionalID = BitSetUtils.bitSetFrom(id); // calculate the optional covariate ID for this covariate
BitSet optionalID = bitSetFromId(id); // calculate the optional covariate ID for this covariate
optionalCovariatesInfo.add(new OptionalCovariateInfo(optionalID, optional)); // optional covariates have standardized mask and number of bits, so no need to store in the RequiredCovariateInfo object
String covariateName = optional.getClass().getSimpleName().split("Covariate")[0]; // get the name of the covariate (without the "covariate" part of it) so we can match with the GATKReport
covariateNameToIDMap.put(covariateName, id);
@ -100,7 +100,7 @@ public class BQSRKeyManager {
public List<BitSet> bitSetsFromAllKeys(BitSet[] allKeys, EventType eventType) {
List<BitSet> allBitSets = new ArrayList<BitSet>(); // Generate one key per optional covariate
BitSet eventBitSet = BitSetUtils.bitSetFrom(eventType.index); // create a bitset with the event type
BitSet eventBitSet = bitSetFromEvent(eventType); // create a bitset with the event type
int eventTypeBitIndex = nRequiredBits + nOptionalBits + nOptionalIDBits; // Location in the bit set to add the event type bits
int covariateIndex = 0;
@ -257,9 +257,20 @@ public class BQSRKeyManager {
eventKey.set(i - firstBitIndex);
return EventType.eventFrom(BitSetUtils.shortFrom(eventKey));
}
private BitSet bitSetFromEvent(EventType eventType) {
return BitSetUtils.bitSetFrom(eventType.index);
// cache the BitSet representing an event since it's otherwise created a massive amount of times
private static final Map<EventType, BitSet> eventTypeCache = new HashMap<EventType, BitSet>(EventType.values().length);
static {
for (final EventType eventType : EventType.values())
eventTypeCache.put(eventType, BitSetUtils.bitSetFrom(eventType.index));
}
private BitSet bitSetFromEvent(final EventType eventType) {
return eventTypeCache.get(eventType);
}
private BitSet bitSetFromId(final short id) {
return BitSetUtils.bitSetFrom(id);
}
private int bitsInEventType() {

View File

@ -5,6 +5,8 @@ import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;
/**
* Utilities for bitset conversion
@ -71,8 +73,15 @@ public class BitSetUtils {
* @return a bitset representation of the short
*/
public static BitSet bitSetFrom(short number) {
return bitSetFrom(number, NBITS_SHORT_REPRESENTATION);
BitSet result = shortCache.get(number);
if (result == null) {
result = bitSetFrom(number, NBITS_SHORT_REPRESENTATION);
shortCache.put(number, result);
}
return result;
}
// use a static cache for shorts (but not for longs, because there could be a lot of entries)
private static final Map<Short, BitSet> shortCache = new HashMap<Short, BitSet>(2 * Short.MAX_VALUE);
/**
* Creates a BitSet representation of an arbitrary integer (number of bits capped at 64 -- long precision)