commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Struberg <strub...@yahoo.de>
Subject proposal for performance/usability optimisations in commons.lang.Validate
Date Sat, 02 May 2009 17:06:56 GMT

Hi!

I'm a long time user (and big fan) of commons.lang.Validate because it's a very neat pattern
for getting stable software modules.

I'm PMC member on Apache OpenWebBeans and currently also writing the maven-scm-provider-jgit
(JGIT is a native Java implementation of GIT). Since jgit-core (the part of EGIT we use for
the maven-scm-provider-jgit) is BSD and Shawn likes to have not too much external dependencies,
I started writing my own little Validate helper class and had a hopefully good idea which
imho would also be a good extension to commons.lang.Validate:

A main problem on validation is the message creation which costs a lot of String operations
and therefor also garbage collection. I've now seen that the latest version in SVN has an
additional object parameter for a few functions which addresses this problem. My proposal
now goes even further but requires java-5 since it uses ellipsis notation.

If msgObject[0] is a String java.text.MessageFormat will be used for creating the failure
message, e.g.
Validate.notNull(nullInt, "testMessageText Integer={0} btw! and Integer2={1}.", new Integer(42),
new Integer(43));

example for isTrue with message construction:

/**
 * Validate that b is <code>true</code>
 * 
 * @param b boolean to validate
 * @param msgObjects additional Objects added as text message to the InvalidArgumentException
 */
public static void isTrue(boolean b, Object... msgObjects) {
	if (!b) {
		throw new IllegalArgumentException(getMessage(msgObjects));
	}
}

/**
 * private helper function to create an error message from the given Objects
 * If the first object in msgObjects is of type {@code String} then 
 * {@code MessageFormat} will be used to format the output message.
 * 
 * @param msgObjects
 * @return concatenated String representation of all the objects
 */
private static String getMessage(Object... msgObjects) {
	if (msgObjects.length > 0 && msgObjects[0] instanceof String) {
		MessageFormat form = new MessageFormat((String) msgObjects[0]);
		Object[] params = new Object[msgObjects.length - 1];
		System.arraycopy(msgObjects, 1, params, 0, msgObjects.length - 1);
		return form.format(params);
	}
	else {
		StringBuffer sb = new StringBuffer("Validation failed: [");
		for(int i = 0; i < msgObjects.length; i++) {
			if (i > 0) {
				sb.append(' ');
			}
			sb.append(msgObjects[i]);
		}
		sb.append(']');
		return sb.toString();
	}
}
	
I've tested those functions against 'old' Validate handling to ensure that there are no performance
side effects with Java ellipsis handling, and the performance win is huge [1]. The ellipsis
Version only takes < 5% of the time of the 'old' handling.

WDYT? 
a.) Is the implementation ok?
b.) Will there be a java-5 only version of commons.lang in the near future?
c.) Imho we could replace the 1-parameter versions with the proper ellipsis functions and
we are still compile compatible. But I'm not sure if we stay binary-compatible (needs to be
tested).

I wrote a Validate class this way for jgit-core [2] but also have to like this features in
our owns commons.lang.Validate if possible!


txs and LieGrue,
strub

[1] http://pastebin.com/m2cf887a9

[2] http://github.com/sonatype/JGit/blob/2ab3a576fa67145d6a9f66efd7437c52d567eb68/org.spearce.jgit/src/org/spearce/jgit/util/Validate.java



      

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message