Archive for June, 2008

Performance testing of new JoomFish 2.0b2 for Joomla!

preamble

JoomFish heavily influences Joomla! performance and with new release of JoomFish we have a question: which performance changes we have with new version of JoomFish 2.0b2.

New revolution today, no just another good enhancement

Testing conditions exactly like in previous test:
I have created virtual dedicated server with following configuration within our server
to have a picture of average hosting providers.

configuration:
architecture: x86
CPU: 3.0Ghz
RAM: 512Mb
OS: Debian GNU/Linux lenny/sid (testing)
kernel: 2.6.22-3-686
CMSs returned specially prepared page contains:
menu, login form, 2 articles with overall size 40Kb
Testing series contains results for 1, 10, and 20 simultaneous users.
Caching functionally turned off.

apache configuration:
apache web-server API: apache2.0 handler
processing model: mpm-prefork [http://httpd.apache.org/docs/2.0/mod/prefork.html]

software versions:
apache: 2.2.8
php: 5.2.5-3
mysql: 5.0.51a-3
joomla!: 1.5.3
joomFish: 2.0b2

Look on these tables and pictures.
I think you don’t need any conclusions because pictures and table are quite plain.

note:
results in the tables are presented in milliseconds per page request
and surely smaller result is better

1 user

joomla joomla + joomfish slowdown beta2, % slowdown beta1, %
average 177 230 23.04 32.18
median 177 223
90% results line 183 234

10 users

joomla joomla+joomfish slowdown beta2, % slowdown beta1, %
average 1497 1888 20.71 28.48
median 1397 1772
90% results line 2019 2571

20 users

joomla joomla+joomfish slowdown beta2, % slowdown beta1, %
average 2748 3588 23.41 33.07
median 2321 3144
90% results line 3506 4520



On-the-fly compilation in Java6

One of interesting novelty of Java6 is a possibility to access compiler via special API.
Let’s look on this feature a bit closer.

In order to have an access to compilation subsystem we should use classes located at javax.tools package [http://java.sun.com/javase/6/docs/api/javax/tools/package-summary.html].
In the future in this package possibly appear classes to work with different external utilities,
but at this moment we have only access to the compiler.

As simple example let’s look on request to compile:

	JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

	Iterable<SimpleJavaFileObject> srcList =  Arrays.asList(new SimpleJavaFileObject[]{
		new SimpleJavaFileObject(URI.create("string:///myclass.java"), Kind.SOURCE) {

			@Override
			public CharSequence getCharContent(boolean ignoreEncodingErrors) {
				return "class myclass {}";
			}
		}
	});
       JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
       compiler.getTask(null, fileManager, null, null, null, srcList).call();

Let’s try to understand how it’s work:

The compiler access input data not directly but via objects inherited form JavaFileObject.
Therefore depending on needs of developer information for compilation can be received from any place:
network, file, memory; for that we need to implement successor of JavaFileObject.
It is better to do it by inheriting class-gag SimpleJavaFileObject

In our example implementation of SimpleJavaFileObject returns source of class as constant string.

It is slightly harder with output data. There is another abstraction layer called JavaFileManager that is
object factory per se.

Standard file manager that we receive in our example let us work with files on the disk. If you need to place output data
on the network on in the memory you need to override JavaFileManager. It is better to do it inheriting
ForwardingJavaFileManager, this class retarget request to provided during creation file manager.
At the same time you can handle only those request that you need.

Last string of example creates compilation command and execute it at once. As a result of execution we have file
in the execution directory of example with name myclass.class that contains bytecode of appropriate class.

It is noteworthy that classloaders of system know nothing about existence of given class and so call
Class.forName(“myclass”) throws ClassNotFoundException.
Let’s complete our example to get class bytecode as byte array. For that we need to implement our own file manager:

public class JavaMemFileManager extends ForwardingJavaFileManager {

	class ClassMemFileObject extends SimpleJavaFileObject {
		ByteArrayOutputStream os = new ByteArrayOutputStream();

		ClassMemFileObject(String className) {
			super(URI.create("mem:///" + className + Kind.CLASS.extension), Kind.CLASS);
		}
		byte[] getBytes() {
			return os.toByteArray();
		}

		@Override
		public OutputStream openOutputStream() throws IOException {
			return os;
		}
	}

	private HashMap<String, ClassMemFileObject> classes =
			new HashMap<String, ClassMemFileObject>();

	public JavaMemFileManager() {
		super(ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null));
	}

	@Override
	public JavaFileObject getJavaFileForOutput(Location location,
			String className, Kind kind, FileObject sibling) throws IOException {
		if (StandardLocation.CLASS_OUTPUT == location && JavaFileObject.Kind.CLASS == kind) {
			ClassMemFileObject clazz = new ClassMemFileObject(className);
			classes.put(className, clazz);
			return clazz;
		} else {
			return super.getJavaFileForOutput(location, className, kind, sibling);
		}
	}

	public byte[] getClassBytes(String className) {
		if (classes.containsKey(className)) {
			return classes.get(className).getBytes();
		}
		return null;
	}
}

As you see our file manager override method getJavaFileForOutput that complier calls to receive output file object.
Here we check destination, for new classes it should be StandardLocation.CLASS_OUTPUT and type.
If it correspond to newly compiled class then we create new file object: we save it and pass it to the compiler.
Then we can receive access to the bytecode with method getClassBytes(className) passing the name of the class.

Let us change previous example to use new functionality:

	....
	JavaFileManager fileManager = new JavaMemFileManager();
	compiler.getTask(null, fileManager, null, null, null, srcList).call();

	byte[] myClassBytes = ((JavaMemFileManager)fileManager).getClassBytes(“myclass”);
	....

And yet one feature of example execution in our case will be absence of file on the disk.

Finally I made a library that makes easier access to Java6 Compiler API.
See details on: [ http://opensource.helion-prime.com/jruntime/ ]

New web-experience with Mozilla Prism

preamble

Our world is currently in transition from traditional desktop applications to web-oriented where most of time we want to do everything in the Web with help of our browsers.
Sometimes nevertheless we want to use some web-applications like: Gmail, Google docs, FaceBook or on-line dictionary as desktop application. Is it possible ? Try the Prism.

prism world

With Prism you can run web-oriented applications directly on desktop in their own window where they have access to all windows features and you still can access these same applications from your web browser.
Prism is built on Firefox so it supports all rich internet technologies and runs on Windows, Mac OS X, and Linux.
Also Prism developers thinking how to integrate better the Prism with Firefox,
enabling one-click “make this a desktop app” functionality that preserves a user preferences.

For more information about Prism go to the project page: [http://developer.mozilla.org/en/docs/Prism]
When invoked it is as pretty as following picture:

google calendar in Prism

getting Started with Prism

download and install appopriate version for your platform:

Prism for Firefox v0.2 for Firefox 3.0b3pre or greater, Windows/Mac/Linux.

The standalone version of Prism v0.9 is also available:
for Windows (installer, archive), Mac and Linux.

Mozilla foundation wants for you

Prism is open source project and if you want to help Mozilla with Prism development go to:
[http://wiki.mozilla.org/Prism]
forum for discussions: [https://labs.mozilla.com/forum/index.php/board,16.0.html]
Bugzilla for bug reporting: [https://bugzilla.mozilla.org/enter_bug.cgi?product=Mozilla+Labs&component=Prism]

Simplify of web-development with Firefox plug-ins

preamble

There is set of plug-ins that really simplify development process and glance will help you select something for your daily work.

golden list

name: firebug
functions: edit, debug, and monitor CSS, HTML, and JavaScript live
hints: page loading analysis, live working with CSS styles, JavaScript debugger
add-on page: [https://addons.mozilla.org/en-US/firefox/addon/1843]

name: user agent switcher
functions: switch the user agent of the browser
hints: cool but IE, and Firefox still interpret code differently and anyway for interpretation tests you need ‘ies4linux’ [http://www.tatanka.com.br/ies4linux/page/Main_Page]
add-on page: [https://addons.mozilla.org/en-US/firefox/addon/59]

name: firesizer
functions: resize of firefox the window to specific dimensions
hints: it helps to test site in required resolutions
add-on page: [https://addons.mozilla.org/en-US/firefox/addon/5792]

name: SQLite manager
functions: manage SQLite databases
hints: I think you know why it is better to use SQLite DB on workplaces
add-on page: [https://addons.mozilla.org/en-US/firefox/addon/5817]

name: add N edit cookies
functions: allows you add and edit session and saved cookies in live
add-on page: [https://addons.mozilla.org/en-US/firefox/addon/573]