Just wrote a very simple application to test the speed on the Android Intent, and compare it with the speed of direct handler call.

As expected, (and documented somewhere), direct function call is much faster than using intent. But how fast is it? here’s the screen captures from 4 runs:

These are done on a Virtual Device with Froyo sits in it, of course, when running in real machine, the speed would be better, but compare the speed of intent and direct function call, the difference is quite significant.(At least 10 times slower).

Following is the code I used:

package com.gueei.intentPerformance;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class PerformanceActivity extends Activity implements OnClickListener {
	TextView textViewIntentLog = null;
	TextView textViewDirectLog = null;

	Handler mUiHandler = new Handler();

	long totalTime = 0;
	int count = 0;

	private Thread intentThread;
	private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getAction().startsWith("com.gueei.intentPerformance")) {
				long fireTime = intent.getExtras().getLong("fire_time", 0);
				int serial = intent.getExtras().getInt("serial", 1);
				log(fireTime, serial, textViewIntentLog);
			}
		}
	};

	private void log(long fireTime, int serial, TextView logger) {
		long receivedTime = System.currentTimeMillis();
		count++;
		totalTime += (receivedTime - fireTime);

		logger.setText("#" + serial + "\ncurrent delay: "
				+ (receivedTime - fireTime) + "\nAverage: "
				+ ((float)totalTime / count));
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		this.findViewById(R.id.btnStartIntent).setOnClickListener(this);
		this.findViewById(R.id.btnStartDirect).setOnClickListener(this);
		textViewIntentLog = (TextView) this
				.findViewById(R.id.textViewIntentLog);
		textViewDirectLog = (TextView) this
				.findViewById(R.id.textViewDirectLog);
		IntentFilter filter = new IntentFilter();
		filter.addAction("com.gueei.intentPerformance");
		this.registerReceiver(intentReceiver, filter);
	}

	public void onClick(View v) {
		// Start firing intent, in a new thread
		if (intentThread != null) {
			if (intentThread.isAlive())
				return;
		}

		count = 0;
		totalTime = 0;
		if (v.getId() == R.id.btnStartIntent) {
			intentThread = new Thread() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					super.run();
					for (int i = 0; i < 100; i++) {
						long fireTime = System.currentTimeMillis();
						Intent fireIntent = new Intent(
								"com.gueei.intentPerformance");
						fireIntent.putExtra("fire_time", fireTime);
						fireIntent.putExtra("serial", i + 1);
						sendBroadcast(fireIntent);
						try {
							this.sleep(100);
						} catch (InterruptedException e) {
						}
					}
				}
			};
		}
		else{
			intentThread = new Thread() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					super.run();
					for (int i = 0; i < 100; i++) {
						mUiHandler.post(new updateLog(i+1, System.currentTimeMillis()));
						try {
							this.sleep(100);
						} catch (InterruptedException e) {
						}
					}
				}
			};
		}

		intentThread.start();
	}

	private class updateLog implements Runnable{
		private int serial;
		private long start;
		public updateLog(int serial, long start){
			this.serial = serial;
			this.start= start;
		}
		public void run(){
			log(start, serial, textViewDirectLog);
		}
	}
}

Forgive me on the poor coding style here, just want to make a quick check to make things work.

Advertisements