MySQL vs. PostgreSQL

|
http://www.wikivs.com/wiki/MySQL_vs_PostgreSQL

오픈 소스 데이터베이스로서의 MySQL과 PostgreSQL이 잘 비교되어 있습니다.
데이터베이스에 대해 공부하기에는 PostgreSQL이 더 좋을 수도 있겠네요. 
저작자 표시
Trackback 0 And Comment 0

RHEL 5.3 에서 PostgreSQL 서버 돌리기

|
참조 1: YoLinux Tutorial: The PostgreSQL Database and Linux
(구글에서 'linux postgresql'을 검색하면 가장 먼저 나오는 글입니다. Tutorial이 잘 구성되어 있습니다.)
참조 2: PostgreSQL Documentation
(정리가 잘 되어 있습니다.)

nxserver 무료버전 설치하려다가 잘 안돼서 나중에 하기로 하고, 그냥 putty로 작업하기로 했습니다. Windows에 PostgreSQL을 설치할 때는 설치마법사를 따라서 쭉 설치하면 되는데, Linux 에서 사용하려니 막막하더군요. 일단 설치는 간단합니다. RHEL 저장소에 PostgreSQL이 있으니 yum을 이용해서 설치하면 됩니다. 일단 yum 명령어를 사용해서 PostgreSQL 을 설치하고 나면, postgres 라는 사용자가 생성되며, /var/lib/pgsql 에 기본 data 폴더가 생성됩니다. 그리고 /etc/rc.d/init.d/ 에 가보면, postgresql 이라는 이름의 스크립트 파일이 있습니다. 기본 폴더를 사용하시지 않는다면 이 스크립트 파일을 수정해주면 됩니다. 

연구실에서 새로 구입한 서버에는 레드햇 서버가 설치되어 들어왔는데, 기본 파일 시스템은 적게 잡혀있고, 나머지 부분은 마운트 되지 않은 상태였습니다. 나머지 부분을 마운트 하고 그곳에 PostgreSQL 서버의 데이터 폴더를 만들기로 했습니다. 

[root@pearl sjlee] grep postgres /etc/passwd
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
위와 같이 해보면, postgres 사용자에 대한 정보를 볼 수 있습니다. X window 상에서는 system-config-users 를 사용하시면 더 쉽게 하실 수 있습니다.  어쨌든 차례대로 사용자 ID, 암호 필드, UID, GID, 이름, 홈디렉토리의 위치, 사용쉘을 나타냅니다. 저의 경우에는 /data/pgsql 를 postgres 사용자의 홈폴더로 사용하고 /data/pgsql/data 폴더를 데이터가 저장되는 디렉터리로 사용하도록 하겠습니다.
[root@pearl sjlee] cd /data
[root@pearl sjlee] su postgres
bash-3.2$ mkdir pgsql
bash-3.2$ cd pgsql
bash-3.2$ cp /var/lib/pgsql/.bash_profile ./
bash-3.2$ exit
[root@pearl sjlee] /usr/sbin/usermod -d /data/pgsql
/data/pgsql 디렉터리를 postgres 사용자 소유로 만들고 원래 홈디렉터리에 있던 .bash_profile을 새로 만든 디렉터리로 복사해옵니다. 그리고 .bash_profile 을 열어보면 다음과 같이 PGDATA 환경변수를 지정하고 있는데, 이 환경변수는 PostgreSQL의 데이터 디렉터리를 지정하므로, 새로 만들 데이터 디렉터리인 /data/pgsql/data 로 되어있는지 확인합니다.
[ -f /etc/profile ] && source /etc/profile

PGDATA=/data/pgsql/data
export PGDATA
이제 initdb 툴을 사용해서 데이터베이스를 초기화합니다.
bash-3.2$ initdb -D /data/pgsql/data
이 데이터베이스 시스템에서 만들어지는 파일들은 그 소유주가 "postgres" id로
지정될 것입니다. 또한 이 사용자는 서버 프로세스의 소유주가 됩니다.

데이터베이스 클러스터는 ko_KR.UTF-8 로케일로 초기화 될 것입니다.
기본 데이터베이스의 UTF8 인코딩은 설정되었습니다.

data 디렉토리 만드는 중 ...완료
data/global 디렉토리 만드는 중 ... 완료
data/pg_xlog 디렉토리 만드는 중 ... 완료
data/pg_xlog/archive_status 디렉토리 만드는 중 ... 완료
data/pg_clog 디렉토리 만드는 중 ... 완료
data/pg_subtrans 디렉토리 만드는 중 ... 완료
data/pg_twophase 디렉토리 만드는 중 ... 완료
data/pg_multixact/members 디렉토리 만드는 중 ... 완료
data/pg_multixact/offsets 디렉토리 만드는 중 ... 완료
data/base 디렉토리 만드는 중 ... 완료
data/base/1 디렉토리 만드는 중 ... 완료
data/pg_tblspc 디렉토리 만드는 중 ... 완료
max_connections 초기값을 선택하는 중 ...100
shared_buffers 초기값을 선택하는 중 ...1000
환경설정 파일을 만드는 중 ...완료
data/base/1 안에 template1 데이터베이스를 만드는 중 ...완료
initializing pg_authid ... 완료
시스템 테이블들을 위한 제한 없는 로우 크기를 활성화 하고 있음 ...완료
initializing dependencies ... 완료
시스템 뷰들을 만드는 중 ... 완료
pg_description 자료 입력 중 ...완료
인코딩 변환규칙(conversion)들을 만드는 중 ...완료
내장객체들의 접근 권한을 설정 중 ... 완료
information schema 만드는 중 ...완료
template1 데이터베이스 vacuum 작업 중 ...완료
template1 데이터베이스를 template0 데이터베이스로 복사 중 ...완료
copying template1 to postgres ... 완료

경고: 로컬 연결의 인증 방법을 "trust" 방식을 지정했습니다.
이 값을 바꾸려면, pg_hba.conf 파일을 수정하든지,
다음번 initdb 명령을 사용할 때, -A 옵션을 사용해서 인증방식을 지정할 수 있습니다.

Success. You can now start the database server using:

    postmaster -D data
or
    pg_ctl -D data -l logfile start
데이터 디렉터리를 초기화하고 나면, 'postmaster -D /data/pgsql/data' 와 같은 명령어로 PostgreSQL Server를 실행할 수 있는데요, 서버가 시작될 때마다 매번 실행시킬 것이기 때문에 PostgreSQL 서버 데몬의 초기화 스크립트를 수정하겠습니다. /etc/rc.d/init.d 에 가면 'postgresql' 이라는 이름으로 초기화 스크립트가 있습니다. 'vi postgresql' 해서 스크립트를 열어보면, PostgreSQL backend daemon 을 시작하고 종료하는 스크립트라는 설명이 있고, 쭈욱 내려가 보면, 아래와 같은 부분이 있습니다.
# Set defaults for configuration variables
PGENGINE=/usr/bin
PGPORT=5432
PGDATA=/var/lib/pgsql
if [ -f "$PGDATA/PG_VERSION" ] && [ -d "$PGDATA/base/template1" ]
then
        echo "Using old-style directory structure"
else
        PGDATA=/var/lib/pgsql/data
fi
PGLOG=/var/lib/pgsql/pgstartup.log
저는 다음과 같이 PGDATA와 PGLOG 를 수정하였습니다.
# Set defaults for configuration variables
PGENGINE=/usr/bin
PGPORT=5432
PGDATA=/data/pgsql
if [ -f "$PGDATA/PG_VERSION" ] && [ -d "$PGDATA/base/template1" ]
then
        echo "Using old-style directory structure"
else
        PGDATA=/data/pgsql/data
fi
PGLOG=/data/pgsql/pgstartup.log
저장하고 파일을 닫고, 이제 PostgreSQL 서버의 설정을 수정하겠습니다. PostgreSQL 서버의 설정 파일에는 postgresql.conf, pg_hba.conf, pg_ident.conf 등이 있습니다.  이중에서 pg_hba.conf 가 PostgreSQL Client Authentication Configutation 파일입니다. 이 파일을 열어보니, PostgreSQL documentation의 "Client Authentication" Section을 참조하라고 되어 있네요. 
제 PC에서 pgAdmin을 사용하는게 편리하기 때문에, 보안상 문제가 있지만, 원격에서 postgres 로그인 롤로 접속할 수 있도록 설정 파일을 수정하도록 하겠습니다.
외부에서 네트워크를 통해 접속하려면 먼저 postgresql.conf의 설정을 확인해야 합니다. postgresql.conf 파일을 열어서 'CONNECTION AND AUTHENTICATION' 부분을 찾습니다.
#---------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#---------------------------------------------------------------------------

# - Connection Settings -

listen_addresses = '*'          # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost', '*' = all
#port = 5432
max_connections = 100
그 중에서 listen_addresses = '*' 으로 설정되었는지 확인합니다. 이 설정에서는 어떤 ip로부터 오는 접속에 응답 대기할 것인가를 지정합니다.
그 다음에 pg_hba.conf 파일을 열어서 수정해주어야 합니다. 이 파일에서는 어떤 호스트에 접속을 허용할 것인지와 접속 방법을 지정합니다. 저는 host all all 172.16.164.213/32 이렇게 추가해 주었는데, 제 pc의 ip인 172.16.164.213/32 에서의 모든 연결과 사용자에 대해 신뢰한다는 것입니다. 이렇게 설정해주고, '/usr/bin/pg_ctl -D /data/pgsql/data restart' 와 같은 명령어로 서비스를 시작해줍니다. 

여기까지하면 172.16.164.213 ip address 를 갖는 제 pc에서 pgAdmin 을 사용해서 postgres 아이디로  원격으로 접속할 수 있습니다. postgres 에는 암호가 설정되어 있지 않아 trust 로 설정되어 있을 경우 데이터베이스에 접속할 수 있습니다. pgAdmin에서 새로운 로그인 아이디를 만든 후에, 원격에서는 이 아이디로만 접속할 수 있도록 설정을 변경하시는 것도 좋을 것 같습니다. 


저작자 표시
Trackback 0 And Comment 0

File Splitting 파일 자르기

|
Personalized Web Search 와 관련해서 ODP(Open Directory Project) 를 참조하고 있습니다. 이 프로젝트에서는 구축된 웹페이지들의 계층구조를 RDF파일로 제공하고 있습니다. 문제는 이 파일이 너무 크다는 것입니다. 1.9GB와 700MB 정도 크기입니다.그래서 간단한 자바 프로그램을 작성하여 파일을 자르기로 했습니다. 싹둑. 검색해보면 '커다란 텍스트 파일을 편하게 잘라주는 프로그램, iHP TxT Split' 와 같은 글들을 찾을 수 있습니다. 어쨌든 연습 삼아 간단하게 자바로 코딩해보았습니다.

FileInputStream과 FileouputStream 을 사용해서 하나의 파일을 원하는 크기로(거의)  잘라주는 코드 입니다.
package kr.ac.uos.dmlab.odp.io.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TextFileSplitter {
	public TextFileSplitter(File srcFile, String destDir) {
		this.srcFile= srcFile;		
		this.destDir= destDir;
	}
	
	private File srcFile;
	private String destDir;
	
	public void split(long preferedSize) {
		String fileName= srcFile.getName();
		
		long srcSize= srcFile.length();		
		long quotient= srcSize/preferedSize;
		int fileNoSpace= getFileNumberSpace(quotient+1);
		
		int fileNo= 0;		
					
		int buffSize= 9096;
		
		try {
			String firstFileName= destDir+formatFileName(fileName, fileNo, fileNoSpace); 
			FileOutputStream fos= new FileOutputStream(new File(firstFileName));
			System.out.println(firstFileName);
			OutputStream os= new BufferedOutputStream(fos);
									
			FileInputStream fis= new FileInputStream(srcFile);
			InputStream is= new BufferedInputStream(fis);
			
			byte buf[] = new byte[buffSize];
			int s = 0;
			long writtenSize= 0;
	
			while ( (s = is.read(buf, 0, buffSize)) > 0 ) {
				if (writtenSize > preferedSize) {
					writtenSize=0;
					fileNo++;					
					os.close();
					String outputFileName= destDir+formatFileName(fileName, fileNo, fileNoSpace);
					System.out.println(outputFileName);
					os= new BufferedOutputStream(new FileOutputStream(new File(outputFileName)));
					
				}
				os.write(buf, 0, s);
				writtenSize= writtenSize + s;
			}
			os.close();
			is.close();
			
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}
	
	private int getFileNumberSpace(long quotient) {
		if (quotient==0) {
			return 1;
		}
		
		int space= 0;
		while( quotient > 0) {
			quotient= quotient/10;
			space++;
		}
		return space;
	}
	
	private String formatFileName(String prefix, int fileNo, int fileNoSpace) {
		int space= fileNoSpace- getFileNumberSpace(fileNo);
		
		
		StringBuffer sb= new StringBuffer();
		
		sb.append(prefix+".part");
		for(int i=0; i< space; i++) {
			sb.append(0);
		}
		sb.append(fileNo);
		
		return sb.toString();
	}
	
		

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TextFileSplitter splitter= new TextFileSplitter(new File("odp/structure.rdf.u8"), "odp/");
		splitter.split(20000000);
	}

}

split 메소드에서 소스 파일을 읽어와서 목적지 디렉터리에 파일을 씁니다. 
이 코드를 사용하면 대강 preferedSize와 비슷한 크기로 파일을 자를 수 있습니다. 
파일을 정확한 크기로 자르지 않는 이유는 그렇게 하려면 원하는 크기까지 쓰고 남은 부분을 따로 저장해놓았다가 다음 번에 쓰는 코드가 추가되어야 하는데, 정확한 크기로  잘라내야 할 이유는 없기 때문에 그냥 두었습니다. 귀차니즘....
클래스 명이 TextFileSplitter인데 그냥 FileSplitter가 맞겠네요.
저작자 표시
Trackback 0 And Comment 0

[Apache Commons]Configuration

|
http://commons.apache.org/configuration/

연구실에서 프로젝트를 할 때, DB 계정 정보 등의 설정 정보 등을 XML파일로 적어놓고 참조하려고 마음을 먹었습니다. 그래서  XML파일 읽는 코드를 한 20줄 짜고, 이 설정 정보를 java.util.Properties 에 저장하여 메모리에 유지하도록 static 하게 변수를 선언하는 등의 작업을 하였으나, 검색해보니 Apache Commons 프로젝트에 Configuration 이라는 컴포넌트가 있습니다.

구글에서 검색하니 http://twit88.com/blog/2007/09/18/xml-configuration-for-java-program/  에도 간단한 예가 나와있습니다. 어쨌든, http://commons.apache.org/configuration/userguide/user_guide.html 를 보시면 이 컴포넌트의 사용방법이 자세하게 기술되어 있습니다. 그리고 User guide의 Hierarchical Properties 항목을 보면, XML파일을 이용하는 방법이 기술되어 있습니다. 

간단히 따라해보았습니다.
먼저 conf.xml 라는 이름의 xml 설정파일을 만들었습니다. 

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<database>
		<server>
			<type>PostgreSQL</type>
			<host>localhost</host>
			<port>5432</port>
		</server>
		<user>				
			<name>coinus</name>
			<password>1124</password>
		</user>
		<database>
			<name>coinus</name>
			<charset>UTF8</charset>
		</database>
	</database>		
</config>
다음은 XMLConfiguration 를 사용해서 XML파일을 읽는 간단한 예제입니다.

package kr.ac.uos.dmlab.config;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;

public class ConfigLoader {
	
	private static XMLConfiguration load(String file) {
		XMLConfiguration conf= null;
		try {
			conf= new XMLConfiguration("conf/conf.xml");
			
			System.out.println(conf.getString("database.server.type"));
		} catch (ConfigurationException e) {
			e.printStackTrace();
		}
		return conf;
	}
	
	public static void main(String[] args) {
		load("conf/conf.xml");
	}
	
}
load()  메소드 중간에 root element인 config 밑의 database 밑의 server 밑의 'type' element의 문자열 값을 가져와서 출력하는 코드가 13 line에 있습니다. 이렇게 element의 value를 문자열이나 정수형 등으로 가져올 수 있습니다. 물론 attribute도 사용할 수 있습니다. 자세한 내용은 User Guide의 Hierarchical Properties 를 참조해주세요. ^^;;

아 그리고 Configuration 컴포넌트의 코드에서 Commons의 다른 컴포넌트들, lang, collections, logging 등이 사용됩니다. 모두 다운 받아서 추가해주어야 합니다. 현재로서는 많은 기능이 필요한 것은 아니지만, 머 훌륭한 코드들일테니 배워두어서 나쁠리 없겠죠.

[딴얘기]
http://gyuha.tistory.com/193 를 감사히 보고 써보니 정말 좋은 것 같군요. 

저작자 표시
Trackback 0 And Comment 0

HashMap은 hash를 사용함

|
바보짓을 했습니다.

n-gram 모델을 과제로써 구현하던 중에, 문자열->정수를 참조하기 위해 사전구조체를 만들어보자는 것이 처음 아이디어였습니다. (전에 다른 것을 만들때는 HashMap을 사용했었습니다.)

트리로 만들어볼까해서 Depth는 문자열에서 각 문자의 인덱스를 가리키고, 자식노드로 갈 때는 다음 글자에 따라 분기하는.. 대강 그림을 그려보면 다음과 같은...
예를 들어 '나무'라는 단어는 '나마' 노드에 들어가 있고, '무지개'라는 단어는 '마자가'노드에 들어가 있는..

결과는 삽질.
24438개의 단어가 들어 있는 구조체 내부의 모든  단어를 한번씩 참조하는 데 걸린 시간은
HashMap은 10 ms,
제가 구현한 트리 구조체는 107 ms.

일단 HashMap을 사용할 때는 String 클래스의 hashCode() 메소드를 사용하게 되는데, 다음과 같습니다.
코드로 볼 때는 해쉬 코드의 성능을 잘 모르겠으니, 실제로 실험을 해보면, 24438 단어 중에 중복된 해쉬값은 258개였고,  그 해쉬값의 대부분은 2번 정도 중복되었습니다. 어쨌든 상당히 좋은 해쉬코드임은 분명할 것 같습니다.

어쨌든 제가 만든 트리는 속도도 느리고, 메모리도 많이 사용하니..쓸모없네요. ㅎㅎ




저작자 표시
Trackback 0 And Comment 0

오픈오피스 메모리 설정

|
리눅스에서 오픈오피스로 논문을 작성하고 있는데, 버벅버벅 대길래 검색해봤는데,

http://www.openoffice.blogs.com/openoffice/memory/
이 글이 검색되었습니다.

오픈오피스의 메모리 설정에 대한 글인데요,
메뉴에서 Tools > Options 를 선택하면, Options창이 뜨고, Openoffice.org > Memory 를 선택하면 아래와 같은 화면을 볼 수 있습니다.


여기서 메모리를 설정해주시면 되는데, 저 위에 참조한 글에서는 다음과 같이 설명하고 있습니다.
  • Undo (되돌리기)
    • Number of steps = 20 (또는 더 적게, 대부분의 사용자는 많게 할 필요가 없습니다.)
  • Graphic cache
    • User for OpenOffice.org = 128 MB
    • Memory per object= 20MB
    • Remove from memory after= 00:10 hh:mm
  • Cache for inserted objects
    • Number of objects = 20(또는 더 적게 설정하세요)
라고 되어있습니다. 그리고 몇 가지 기능이 제한되지만 JRE를 끄는 방법을 설명하고 있습니다.
어쨌거나 저는 위의 그림처럼 설정해놓고 사용하니 좀 빨라진것 같기도 합니다.

어쨌든 OpenOffice는 아직도 갈 길이 먼것 같습니다. 그나저나 썬이 오라클에 인수되면서 오픈 오피스는 어떻게 될까요. 지금 구글에서 sun oracle openoffice 로 검색해보니, 흥미로운 글들이 검색되는데, 시간있을 때 읽어봐야 겠네요. Larry Ellison이라는 이름이 많이 나오네요. Oracle CEO 네요...ㅡㅡㅋ

저작자 표시
Trackback 0 And Comment 0

Perl vs Java 간단한 정규표현식 문자열 치환 성능

|
요즘 수업중에 Perl을 아주 조금 써보고 있는데, Perl의 성능이 궁금해서 찾아보는데, 최근 결과가 별로 없어서 간단한 정규표현식 테스트를 직접해보았습니다. 알파벳과 한글이 같이 있는 문자열에서 알파벳을 알파벳이 아닌 문자를 '_'로 바꾸는  테스트입니다. 정규표현식 문자열 치환 테스트를 하는 이유는 펄에서 정규표현식을 언어수준에서 잘 지윈하고 있기 때문입니다.
CPU Q6600, Memory 4G, Fedora 10 x86_64, Java는 openJDK 1.6 x86_64, Perl은 perl.x86_64 에서 이클립스로 작성후 테스트.

결론부터 말씀드리자면 일단 속도에서는 자바 완승,
메모리는 Perl 완승 입니다.

실제 코드는 다음과 같습니다.
자바
StringBuilder 를 사용해서 문자열을 붙이고 String 클래스의 replaceAll 메소드를 사용해서 치환합니다.

다음은 펄.
. 를 사용해서 문자열을 붙이고, s/ / /g를 사용해서 치환합니다.
펄에서도 미리초를 가져오는 모듈도 있는데, 제가 아직 모듈을 설치할 줄 모르고 귀찮아서 패스...

어쨌거나 문자열을 붙이는 데 걸리는 시간
자바 2.514초
펄    2 초
펄 결과는 초단위므로 비교어려움. 거의 유사한 속도를 보인것으로 보임.

다음은 치환하는데 걸리는 시간.
자바 6.860초
펄    27초
자바가 펄보다 4배 정도 빠름

충격적인 결과. 메모리 사용량(System Monitor를 통해 눈으로 확인)
자바
문자열 생성할 때의 메모리 사용량 650M 정도
문자열 치환할 때의 메모리 사용량 950M 정도

문자열 생성할 때의 메모리 사용량 290M 정도
문자열 치환할 때의 메모리 사용량 389M 정도
자바가 펄보다 2배나 메모리 많이 사용함

...사실 2억자를 파일에 써보니(UTF-8) 400,000,040 bytes 가 되네요. 대략 400메가 정도?
펄이 파일에 기록한 후의 크기보다 적은 메모리를 사용한 다는 것이 인상적이네요. 메모리엔 그냥 정수도 갖고 있어서 그런가...

...
어쨌든 자바가 펄보다 더 빠르긴 하네욥.

트랙백 주신 글이나 댓글을 보면, 펄에서 utf-8 인코딩을 사용하는 방법이나 치환 방법에 문제가 있었습니다.
펄을 잘 모르는 초보자의 성급한 결론이었습니다.
^^;;;;;
저작자 표시
Trackback 1 And Comment 4

페도라 10 데스크탑 효과

|
System > Preferences > Look and Feel > Desktop Effects 에서 데스크탑 효과를 켤 수 있습니다.
Compiz Fusion 의 일부 기능만 들어있는 것인지, 다른 GUI를 설치하면 다른 효과도 적용시킬 수 있는지는 모르겠지만 어쨌든 Fedora 10에 적용되어 있는 기본 기능만 사용하고 있습니다.

이 기능이 사양을 좀 타는 것 같아서 사용안하다가 사양이 좀 더 좋은 피씨로 바꾼 다음부터는 켜놓고 사용하고 있습니다. 기능 중에서 제가 제일 좋아하는 것은 바로


이것입니다. 마우스를 오른쪽 상단으로 가져가면 현재 띄워져 있는 창들을 요렇게 보여주는데, 다른 사람이 쓰는 맥에서 살짝 보고 완전 멋있다고 생각했었는데, 이런 기능이 있을 줄은 생각도 못했습니다. 그나저나 요거 단축키는 없나요.
저작자 표시
Trackback 0 And Comment 0

정규표현식을 사용해서 문자열에서 한글만 가져오기

|
문서에서 단어를 추출하는 작업을 하고 있는데,
문자열에서 한글만 가져와야 할 일이 생겼습니다.

문자열에서 한글만을 가져오기 위해 두 가지 방법을 생각했습니다.
일단 한글이 정의되어 있는 유니코드 영역은 AC00-D7AF, 1100-11FF, 3130-318F입니다.
이 영역에 대해서는 [유니코드] 한글과 한자 영역 또는 http://www.unicode.org/charts/에서  Korean-specific 부분을 참조해주세요.

첫번째는 그냥 첫번째 문자부터 읽어서 한글이면 StringBuffer에 append하고 아니면 공백문자를 append하는 방법입니다.

위와 같이 무식하게 char하나하나 확인하는 방법이 되겠습니다.

두번째는 정규표현식을 사용해서 한글이 아닌 문자를 공백문자로 바꾸는 것입니다.
아래와 같이 replaceAll 의 첫번째 argument에는 정규표현식을, 두번째 argument에는 대신 교체된 공백문자를 넣습니다.

정규표현식은 두가지를 고려했습니다.
1. [^\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F]
이 첫번째 정규표현식은 문자 하나하나를 비교하는 첫번째 방법과 같은 방식을 취하게 됩니다. 문자 하나하나를 확인해서 공백문자를 바꾼다는 의미를 갖게 됩니다.

2. [^\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F]+
두 번째 정규표현식은 마지막에 +를 더했습니다. 하나 이상에 매칭된다는 의미인데, 이렇게 하면 여러 개의 한글이 아닌 문자가 하나의 공백문자로 교체됩니다.

...
그리고 임의로 긴문자열을 만들어 실험했습니다.
한글, 영문 포함 2,000,000 자의 문자열에 대해 개별 char직접 확인과 두 개의 정규 표현식을 이용한 방법 등 세가지 방법을 사용해봤습니다.

걸린 시간은
개별 char  직접확인 :  138 ms
첫번째 정규표현식   :  308 ms
두번째 정규표현식   :  108 ms
입니다.

그렇군요. 두번째 정규표현식을 사용하는 것이 가장 짧은 시간 안에 결과를 반환해 주었습니다.

오늘의 교훈! 정규표현식을 적절하게 사용하자! 입니다. 핫핫핫.



저작자 표시
Trackback 0 And Comment 0

Perl, 누구냐 넌.

|
웹 마이닝에 관련된 대학원 수업 때 Perl을 이용하게 되었습니다.

먼저 해봤어야 하는 일이지만, 이클립스에 Perl플러그인을 설치하고 print 해보다가,
구글에서 perl을 검색해보았습니다.

http://kldp.org/node/74080 이 글이 검색되더군요.

교수님께서 Perl 을 사용한다고 하셨을 때,
Perl을 왜? java 도 정규표현식을 지원하는 걸. 하면서 툴툴 댔는데,

저 글을 비롯한 몇 개의 글을 읽어보면서
이번 기회에 Perl을 잘 배워놔야겠다는 생각을 했습니다.


저작자 표시
Trackback 0 And Comment 1
prev | 1 | 2 | 3 | 4 | 5 ... | 7 | next