[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends:00407] Re: 文字列にある文字列が含まれるかどうかを調べる方法 ( 大文字小文字を区別しない)



こんにちわ。大島です。
早速、試してみました。

今回やったテストでは、早い順では、 Perl, Java(すべて大文字統一)、Java
(Pattern クラス使用)という結果になりました。


今回やったテストの結果からわかったことは、多量のテキストファイルで、
大文字小文字をくべつせずに文字列検索を行うには Perl > Java(すべて大文字
統一) > Java(Pattern_クラスを使用する)の順に早いということです。

ただ、今回のテスト結果から単純に文字列検索処理として Perl が Java より
早いといことはいえないかもしれないとおもいました。 ファイルの IO が
Perl の方が Java より早いかもしれないからです。この点詳しい方が
いらっしゃいましたら、教えてください。

以上の結論で、なにかおかしいところがあればご指摘いただけると
幸いです。


_テスト概要
- 約22KB のテキストデータファイルに「yukie」という文字列が
含まれるかどうか(大文字小文字をくべつせずに)検索する
- 1000 回、10000回、100000回でそれぞれの時間を計る(ミリ秒)

テスト結果
1000 10000 100000
-----------------------------------
Perl 2000 13000 136000
Java1 4538 47976 443808
java2 6924 72211 717431

*Perl は 秒単位の計測だったのでミリ秒にするために x 1000 してあります。
*Java1 - すべて大文字に統一
*Java2 - Pattern クラスを使用


ソースは以下の通りです。今回のテスト結果についてテスト方法として
問題がなかったかどうかを指摘していただけると幸いです。



$ cat match_1000.pl
#!/usr/bin/perl

use strict;
use warnings;

my $string = "yukie";

print "Start ...\n";
my $date1 = time();

for (my $i = 0; $i < 1000; $i++) {
open(FH, "data.txt") or die "open: $!";
flock(FH, 1);
while (<FH>) {
if (/$string/io) {
#print "MATCH\n";
}
}
flock(FH, 8);
close(FH);
}
my $date2 = time();
my $date = ($date2 - $date1) * 1000;
print "END $date\n";



$ cat Match1.java
cat: Match1.java: No such file or directory
$ cat Match1_1000.java
import java.util.*;
import java.io.*;

public class Match1_1000 {
public static void main(String[] args) {
String string = "yukie".toUpperCase();
System.out.println("Start...");
Date d1 = new Date();
long date1 = d1.getTime();
for (int i = 0; i < 1000; i++) {
try {
BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = reader.readLine()) != null) {
int offset = line.toUpperCase().indexOf(string.toUpperCase());
/*
if (offset != -1) {
System.out.println("MATCH");
}
*/

}
reader.close();
}
catch (Exception e) {
System.out.println(e);
}

}
Date d2 = new Date();
long date2 = d2.getTime();
long date = date2 - date1;
System.out.println("END "+date);

}
}
$ cat Match2_1000.java
import java.util.*;
import java.io.*;
import java.util.regex.*;

public class Match2_1000 {
public static void main(String[] args) {
String string = "yukie";
Pattern p = Pattern.compile(".*"+string+".*");
System.out.println("Start...");
Date d1 = new Date();
long date1 = d1.getTime();
for (int i = 0; i < 1000; i++) {
try {
BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
boolean b = m.matches();
//int offset = line.toUpperCase().indexOf(string.toUpperCase());
/*
if (offset != -1) {
System.out.println("MATCH");
}
*/

}
reader.close();
}
catch (Exception e) {
System.out.println(e);
}

}
Date d2 = new Date();
long date2 = d2.getTime();
long date = date2 - date1;
System.out.println("END "+date);

}
}
$



Yukie Oshima wrote:

>石黒さん、大崎さん、
>
>おはようございます。大島です。
>私の問いに対してご意見ありがとうございます。
>
>石黒さんのおっしゃること「コンピュータのアーキテクチャに
>もう少し考えを届かせた方がよい」というのはもっとも
>だと思います。
>
>ですが、私はコンピュータ内部で、正規表現がどのように計算されてマッチ
>を行うのか具体的にはよくわからないで、「すべて大文字小文字にするか」
>と「Patter クラスをつかう」がどちらがパフォーマンスがよくなるか
>想像できません。
>
>ですので、実際にやってみたいと思います。
>
>あと、Perl だったら一発でできるのに。。というのは、方法として
>そういうマッチの方法が Perl にはあるのに Java にはないのだなあ
>ということが言いたかっただけで、だから Perl のが パフォーマンスが
>よいといことではありません。これもやっぱり検証などして確かめなくては
>分からないことだと思います。
>
>
>以上です。宜しくお願い致します。
>
>
>
>
>大崎 洋平 wrote:
>
>  
>
>>大崎です。
>>
>> 
>>
>>    
>>
>>>>今回は、たくさんのデータを検索するので、すべて小文字か大文字に
>>>>するのはちょっとパフォーマンスが悪くなるのでは。。とおもった
>>>>     
>>>>
>>>>        
>>>>
>>>思うのは自由ですが、ちょっと筋が悪いと思います。
>>>コンピュータのアーキテクチャにもう少し考えを届かせたほうがよいか
>>>と思います。
>>>   
>>>
>>>      
>>>
>>.... snip ...
>>
>> 
>>
>>    
>>
>>>>すべて小文字か大文字で統一して indexOf で調べるのが
>>>>     
>>>>
>>>>        
>>>>
>>>やり方としておかしくないし、効率的であることが想像できます。
>>>   
>>>
>>>      
>>>
>>そうでしょうか?
>>indexOf()を使った場合、検索対象の文字列と同じサイズの文字列をもう一つ作
>>ることになりますよね。
>>そして、そのすべての文字列を調べて、大文字、小文字を入れ替えることになり
>>ますよね。
>>本当に効率的だといえますか?
>>
>>正規表現を使う場合、部分的にもマッチしない箇所は比較が行われないはずです。
>>(つまり、大文字、小文字の変換も行われません。)
>>私にはこちらのほうが効率的に思えるのですが。
>>
>>大島さんの調査報告をお待ちしております。
>>
>> 
>>
>>    
>>
>
>
>
>  
>