ประสิทธิภาพ regular expression

จากเรื่อง Count number of charactor in String ก่อนหน้านี้ พอดีมีงานลักษณะเดียวกัน แต่เป็นการอ่านข้อมูลจาก text file ที่มีขนาดประมาณ 1MB และมีข้อมูลตัวอักษรประมาณ 1,017,825 ตัว ผลการทดลองอย่างคร่าวๆได้ผลว่าการเขียน code แบบวน loop ตัดอักษรทีละตัวมาตรวจสอบนั้นทำงานได้ไวกว่าแบบใช้ regular expression ตัวอย่าง code การทดสอบ เผื่อใครจะเห็นว่า
เขียนได้ห่วยเอง มันเลยไม่ได้ประสิทธิภาพ ผลการทดสอบดังนี้
แบบธรรมดา

private static void test1(String data) {
	int found = 0;
	long start = System.currentTimeMillis();
	for (int i = 0; i < data.length(); i++) {
		found += ('M' == data.charAt(i)) ? 1 : 0;
	}
	long end = System.currentTimeMillis();
	System.out.println("Data : " + data.length());
	System.out.println("Found : " + found);
	System.out.println("Start : " + start);
	System.out.println("End : " + end);
	System.out.println("Diff : " + (end - start));
}

ผลการรัน

Data : 1017825
Found : 42880
Start : 1266287262406
End : 1266287262421
Diff : 15


แบบ regular expression

private static void test2(String data) {
	long start = System.currentTimeMillis();
	int count = data.replaceAll("[^M]", "").length();
	long end = System.currentTimeMillis();
	System.out.println("Data : " + data.length());
	System.out.println("Found : " + count);
	System.out.println("Start : " + start);
	System.out.println("End : " + end);
	System.out.println("Diff : " + (end - start));
}

ผลการรัน

Data : 1017825
Found : 42880
Start : 1266287262421
End : 1266287262718
Diff : 297

สรุปคร่าวๆตอนนี้ก็คงเลือกแบบที่เขียนเช็คเองไปก่อน เนื่องจากข้อมูลที่ต้องการนำไปใช้นั้นจะมีขนาดใหญ่พอสมควร จากการทดลองถ้าข้อมูลไม่มากนัก เวลาในการทำงานของแต่ละแบบไม่ต่างกันเลยครับ
Code ทั้งหมดที่เขียนเป็นดังนี้

/**
 * File Name : ReadHTMLData.java
 * Created Date : Jan 12, 2010 : 9:56:09 AM
 * Copyright © 2010 www.fun4station.com
 */
package com.fun4station.test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * @Author Supot Saelao
 * @Version 1.0
 */
public class TestRexg {

	public static void main(String[] args) {
		//Read data from text file
		String data = proccessData();
		//Use normal way
		test1(data);
		//Use regular expression
		test2(data);
	}

	private static void test1(String data) {
		int found = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < data.length(); i++) {
			found += ('M' == data.charAt(i)) ? 1 : 0;
		}
		long end = System.currentTimeMillis();
		System.out.println("Data : " + data.length());
		System.out.println("Found : " + found);
		System.out.println("Start : " + start);
		System.out.println("End : " + end);
		System.out.println("Diff : " + (end - start));
	}
	
	private static void test2(String data) {
		long start = System.currentTimeMillis();
		int count = data.replaceAll("[^M]", "").length();
		long end = System.currentTimeMillis();
		System.out.println("Data : " + data.length());
		System.out.println("Found : " + count);
		System.out.println("Start : " + start);
		System.out.println("End : " + end);
		System.out.println("Diff : " + (end - start));
	}

	private static String proccessData() {

		BufferedReader dataIns = null;
		try {
			dataIns = new BufferedReader(new FileReader("data.txt"));
			return dataIns.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				dataIns.close();
			} catch (IOException e) {
			}
		}
		return null;
	}
}

หมายเตุ
เป็นทดสอบแบบไม่มีหลักการอะไรมาก และ อาจเพราะใช้ regular expression แบบไม่เหมาะสมกับงานก็ได้ครับ
Update เพิ่มเติม กรณีใช้ String.replaceAll นั้นดู ไม่ยุติธรรมเอาซะเลย เพราะ replaceAll มีการแก้ไข String ส่วน count แบบธรรมดา ไม่มีการเปลี่ยนแปลง String เดียวต้องหาวิธีการใหม่แล้วละครับ

  1. No comments yet.

  1. No trackbacks yet.