As a follow-up to the lengthy conversation we had about java.util.Random and whether it is best to reuse a single one and synchronize on it or just create a new one each time, I wrote a program to compare the performance of the two. Here are the results (CentOS 4.4, JDK 6):

Testing with 1 threads for 5 seconds
Generated 1,191,083 random ints using seed-many method
Generated 24,562,853 random ints using seed-once method
====================
Testing with 5 threads for 5 seconds
Generated 1,736,231 random ints using seed-many method
Generated 11,417,596 random ints using seed-once method
====================
Testing with 10 threads for 5 seconds
Generated 1,749,759 random ints using seed-many method
Generated 10,706,179 random ints using seed-once method
====================
Testing with 25 threads for 5 seconds
Generated 1,727,634 random ints using seed-many method
Generated 10,922,547 random ints using seed-once method
====================
Testing with 50 threads for 5 seconds
Generated 1,732,329 random ints using seed-many method
Generated 10,734,163 random ints using seed-once method
====================

The difference was less pronounced under Windows XP (JDK 6), but seed-once still won:

Testing with 1 threads for 5 seconds
Generated 2,335,585 random ints using seed-many method
Generated 45,853,345 random ints using seed-once method
====================
Testing with 5 threads for 5 seconds
Generated 3,290,170 random ints using seed-many method
Generated 6,214,038 random ints using seed-once method
====================
Testing with 10 threads for 5 seconds
Generated 3,283,141 random ints using seed-many method
Generated 6,706,248 random ints using seed-once method
====================
Testing with 25 threads for 5 seconds
Generated 3,258,902 random ints using seed-many method
Generated 6,597,599 random ints using seed-once method
====================
Testing with 50 threads for 5 seconds
Generated 3,244,338 random ints using seed-many method
Generated 6,650,498 random ints using seed-once method
====================

The source code is attached. If I messed up anywhere, please let me know.

-Ben

package test;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RandomTest {

	static class SeedMultiple implements Runnable {
		static int activeThreads = 0;

		static boolean stop = true;

		static int count = 0;

		public void run() {
			++activeThreads;
			while (stop)
				Thread.yield();
			while (!stop) {
				new Random().nextInt();
				++count;
			}
			--activeThreads;
		}

		public static void reset() {
			stop = true;
			count = 0;
		}
	}

	static class SeedOnce implements Runnable {
		static int activeThreads = 0;

		static Random random = new Random();

		static boolean stop = true;

		static int count = 0;

		public void run() {
			++activeThreads;
			while (stop)
				Thread.yield();
			while (!stop) {
				synchronized (random) {
					random.nextInt();
				}
				++count;
			}
			--activeThreads;
		}

		public static void reset() {
			stop = true;
			count = 0;
		}
	}

	public static void runTest(int threadCount, long sleepSeconds)
			throws InterruptedException {
		DecimalFormat format = new DecimalFormat(",###");

		// info
		System.out.println("Testing with " + threadCount + " threads for "
				+ sleepSeconds + " seconds");

		// test the seed-many method
		SeedMultiple.reset();
		List<Thread> threads = new ArrayList<Thread>();
		for (int i = 0; i < threadCount; i++) {
			Thread thread = new Thread(new SeedMultiple());
			thread.start();
			threads.add(thread);
		}
		SeedMultiple.stop = false;
		Thread.sleep(sleepSeconds * 1000);
		SeedMultiple.stop = true;
		while (SeedMultiple.activeThreads > 0)
			Thread.yield();
		System.out.println("Generated " + format.format(SeedMultiple.count)
				+ " random ints using seed-many method");

		// test the seed-once method
		SeedOnce.reset();
		threads.clear();
		for (int i = 0; i < threadCount; i++) {
			Thread thread = new Thread(new SeedOnce());
			thread.start();
			threads.add(thread);
		}
		SeedOnce.stop = false;
		Thread.sleep(sleepSeconds * 1000);
		SeedOnce.stop = true;
		while (SeedOnce.activeThreads > 0)
			Thread.yield();
		System.out.println("Generated " + format.format(SeedOnce.count)
				+ " random ints using seed-once method");
	}

	public static void main(String[] args) throws InterruptedException {
		int[] threadCounts = new int[] { 1, 5, 10, 25, 50 };
		long sleepSeconds = 5;
		for (int count : threadCounts) {
			runTest(count, sleepSeconds);
			System.out.println("====================");
		}
	}

}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to