2014年8月26日火曜日

@EJBと@INJECTの違い

どっちも依存性注入(Dependency Injection:DI)のために使うアノテーション。

違いは@EJBがejbしか注入できない一方、@INJECTはejbを含めてなんでも注入できること。

参考文献
Should I use @EJB or @Inject

量指定子(greedy,reluctant,possessive)による性能の違い

以前に正規表現における量指定子(greedy,reluctant,possessive)とはなにかというタイトルでブログを書きましたが、その時に調べた公式ドキュメントには量指定子によって性能差があると書いてありました。

具体的には、possessiveはgreedyに比べてバックトラックを行わないため実行速度が早い、とのことです。

試しにそれぞれの量指定子による正規表現マッチを1000万回行うコードを書いたところ、実行速度は次のようになりました。

greedy :7297 ms
reluctant :6125 ms
possessive :19624 ms

確かにpossessiveに比べてgreedyのほうが早いです。実行速度にして1/3から1/2程度。

性能にシビアなコードを書くときは意識した方が良さそうですね。



付録 測定に使ったコード(リンクしたgistと同じもの)

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExpTest {

 private static String str = "xfooxxxxxxfoo";
 private static int max = 10000000;
 public static void main(String args[]){

  runGreedy();
  runReluctant();
  runPossessive();
 }
 
 public static void runGreedy(){
  long before = System.currentTimeMillis();
  String regex = ".*foo";

  for(int i = 0; i < max ; i++){
   Pattern p = Pattern.compile(regex);
   Matcher m = p.matcher(str);
   m.find();
  }
  
  long after = System.currentTimeMillis();
  
  System.out.println("greedy :" + (after - before));
 }
 
 public static void runReluctant(){
  long before = System.currentTimeMillis();
  String regex = ".*?foo";

  for(int i = 0; i < max ; i++){ 
   Pattern p = Pattern.compile(regex);
   Matcher m = p.matcher(str);

   m.find();
  }
  
  long after = System.currentTimeMillis();
  
  System.out.println("reluctant :" + (after - before));
 }

 public static void runPossessive(){
  long before = System.currentTimeMillis();
  String regex = ".*+foo";

  for(int i = 0; i < max ; i++){
   Pattern p = Pattern.compile(regex);
   Matcher m = p.matcher(str);
   m.find();
  }
  
  long after = System.currentTimeMillis();
  
  System.out.println("possessive :" + (after - before));
 }
}


2014年7月24日木曜日

InitialContextを使ったディレクトリ操作のサンプル

EJBやRMIなどを利用しているとよく目にするInitialContext。公式ドキュメントを読んでいたら、どうやら、ファイルシステムもlookupしたりすることができるみたいです。

ファイルシステム以外にも、LDAPやDNSの検索ができたり、思ったよりも多機能な様子です。

そこで、指定したディレクトリ配下にあるファイルを出力するサンプルコードを書いてみました。
サブディレクトリがある場合は、その下を再帰的にほってファイル名を探しにいきます。




import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.util.Hashtable;
import com.sun.jndi.fscontext.RefFSContext;

class JNDIFileLookup {
 public static void main(String[] args) {

  String root = "file:/";
  Hashtable env = new Hashtable(11);
  env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.fscontext.RefFSContextFactory");
  env.put(Context.PROVIDER_URL, root);

  try {
   Context ctx = new InitialContext(env);
   listFiles(ctx);
  } catch (Exception e) {

  }
 }

 private static void listFiles(Context context) {
  NamingEnumeration list;
  try {
   list = context.list("");
   while (list.hasMore()) {
    NameClassPair nc = (NameClassPair) list.next();
    Object sub = context.lookup(nc.getName());

    if (sub instanceof RefFSContext) {
     listFiles((RefFSContext) sub);
    } else {
     System.out.println(sub);
    }

   }
  } catch (NamingException e1) {

   e1.printStackTrace();
  }

 }

}

なお、filesystem操作用のサービスプロバイダーは標準で用意されていないようで、fscontext.jarを落としてくる必要があります。

公式のドキュメントでもjarのリンクが張ってあったんですが、com.sunの下にリンクがはられており、リンク切れでたどり着くことができませんでした。

そのため、私はこちらからjarを落として使いました

参考文献



2014年7月17日木曜日

正規表現における量指定子(greedy,reluctant,possessive)とはなにか

Javaの正規表現では、quantifier(量指定子)の種類としてGreedy、Reluctant、Possessiveというものがある。

webを検索すると説明はいろいろ出てくるが、日本語の付け方が違ったり、3つを並べて比較してなかったりしてわかりづらかったので、これの違いを整理してみる。

まずquantifier(量指定子)とはなにか。

これは"量"指定子という名称の通り、一致させたい文字の数を指定するための表現方法。

例えば、テキストファイルを検索するためによく使われる下記の表現。

.*\.txt

これは任意の文字が0個以上続いたあとに、".txt"が続く文字列を表現したものであり、*がquantifier(量指定子)に当たる。

Greedy Quantifier

greedy(欲張り)と名前が付いている通り、この量指定子を使うとなるべく多くの繰り返し数になるようにマッチする。

たとえば下記の例がGreedy Quantifier。

.*foo
このとき、xfooxxxxxxfooという文字列にマッチさせようとすると、次の文字列がマッチする。

xfooxxxxxxfoo

Reluctant Quantifier

 reluctant(気乗りしない)と名前がついており、この量指定子を使うとなるべく少なくなる繰り返し数になるようににマッチする。

下記の例がReluctant Quantifier

.*?foo
このとき、先ほどと同様にxfooxxxxxxfooという文字列にマッチさせようとすると、次の文字列がマッチする

xfoo

 Possessive Quantifier

 possesiveは「所有の」という意味がある。この量指定子を使うとGreedyと同様になるべく多くの繰り返し数になるようにマッチする。Greedyとの違いは、正規表現全体のマッチよりも、Possessive Quantifierを使った部分のマッチが優先される、ということ。

例えば下記の例がpossessive quantifier。

.*+foo
同様にxfooxxxxxxfooにマッチさせようとすると、結果は何にもマッチしない。
なぜなら、".*+"がなるべく多くの繰り返し数になるようにマッチするため、この部分だけでxfooxxxxxxfoo文字列全体がマッチする。そのため、fooの部分が一致する場所がなくなり、全体としてはマッチしない、という結果になる。


ここで、それぞれのQuantifierとfooの部分がマッチした箇所を整理すると次のようになる。

Greedy

Quantifierがヒットした場所  xfooxxxxxx
fooがヒットした場所 foo

Reluctant

Quantifierがヒットした場所  xfoo
fooがヒットした場所 xxxxxxfoo

Possessive

Quantifierがヒットした場所  xfooxxxxxxfoo
fooがヒットした場所 なし


参考文献




2014年7月2日水曜日

MIBとSMIとASN.1

SNMP(Simple Network Management Program)を調べているとよく目にする


  • MIB(Management Information Base)
  • SMI(Structure of Management Information)
  • ASN.1 (Abstract Syntax Notation One)


について整理してみました。

MIBとはなにか

SNMPで通信を行う際に、やりとりされるデータのこと。

SMIとはなにか

MIBがどのような値(整数値、文字列等)を取れるか定義したもの。
SNMPというプロトコルを表現するための記法といえる。

ASN.1とはなにか

SMIを定義したもの。SMIはASN1.1の一部、と表現されることもある。
ASN.1自体は古くからプロトコルの定義のために使われており、SNMP以外にも応用の範囲は広い。

まとめると

SNMPでは、MIBというデータがやりとりされる。
で、そのMIBを定義するために、古くからあるASN.1というものを用いて、SMIという記法を作った、という感じだろうか。




2014年6月8日日曜日

Spotifyを使ってみて思った。音楽にお金を出すということ。

Spotifyを使ってみた

音楽ストリーミングサービスのSpotifyを使ってみました。Spotify日本では消費者を置き去りにした業界の事情によりまだ使えないみたいですが、すでに全世界で2000万人を越えるユーザがいる大人気サービスです。

僕はいまアメリカにいるので、何も後ろめたいこともせずに普通に楽しめているわけですが、正直な感想としてこれがタダで使えるのは非常に革新的に思えます。

Spotify自体は日本にいることから知ってましたが、実はYoutubeやTuneInで音楽は聞いていたので、まあ同じようなもんだろうと思って大して期待してませんでした。

しかしながら使ってみると、使い勝手の満足度として大きな違いがあります。
理由としては大きく以下の2つがあげられると思います。

1. 配信している楽曲数が多い
2. 楽曲の選び方の自由度が高い

Spotifyでは1500万以上の楽曲があるようです。
音楽というのは気分や日によって聞きたいものが全く違ったりするので、やはりバラエティは非常に重要です。

またアーティスト・楽曲を選択して再生できます。
ときどきピンポイントで聞きたくなる曲があるので、これは個人的に非常に満足度が高いです。

加えてロック、ポップなど「ジャンル」で指定できるもはもちろんのこと、パーティやロマンティックなど「気分」で指定することも可能です。指定すれば、適当に選択された音楽がエンドレスに流れるのでなんとなく音楽を流したいときとしては最適です。

TuneInとかYoutubeよりも多数の楽曲の選択肢の中から、聴きたい曲をきめ細やかに選べるので、これも非常に満足度が高いです。


楽曲購入はiPhoneの有料アプリを買うくらい抵抗がある行為になる

無料でここまで音楽が自由自在に聴けることを考えると、今後はますます音楽を購入するハードルが高くなる気がします。CD不況は久しく騒がれてますが、かと言って多少安いデジタルデータならば売れるという状況にもならなそうです。

楽曲を購入するという需要は決してなくならないとは思いますが、お金を出すという意味において、配信サービスと楽曲の購入という関係は、iPhone(Andoroid)の無料アプリと有料アプリのような関係になるのではないかな、と想像しています。

つまりリスナーにとって配信サービスを利用するのはiPhoneの無料アプリを使うようなもので、逆に音楽を購入するというのは有料アプリを買うようなもの。

現在、多数の高品質な無料アプリが手に入るようになったがために、100円のアプリですら購入のハードルが高く感じる方は多くいると思います。同様に、今後は音楽にお金を出すのに非常に抵抗を感じる方が多くなってくるのではないでしょうか。特にCDを購入した経験がほとんどない若い人たちを中心に。


おまけ

spotifyの感想ブログを貼っておく。










2014年6月5日木曜日

html5のcanvasで多角形を書いてみた

html5のcanvasタグを使って3角形,4角形,5角形といった多角形を書いてみました。

一応999角形まで表示できますが、これくらいの大きさだと50角形を超える辺りで全部円にしか見えなくなりますね。

三角形

 六角形

 十二角形

 五十角形




<!DOCTYPE html>
<html>

<head>
<script language="javascript">
var radius = 150;
var center_x = 200;
var center_y = 150;

function draw_polygon(){
    var vertex = document.forms["vertex"]["quantity"].value;

 var a = 2 * Math.PI / vertex;
 var arr_x = [];
 var arr_y = [];

 for(var i= 0; i < vertex; i++){
   var rad =(i + 1) *  2 * Math.PI / vertex;
   arr_x[i] = center_x + radius * Math.cos(rad);
   arr_y[i] = center_y + radius * Math.sin(rad);

 }

 var canvas = document.getElementById("myCanvas");
 var ctx = canvas.getContext("2d");
 ctx.clearRect(0,0,canvas.width,canvas.height);
 ctx.beginPath();
 ctx.moveTo(arr_x[0],arr_y[0]);
 for(var i= 1; i < vertex; i++){
     ctx.lineTo(arr_x[i],arr_y[i]);
 }
 ctx.lineTo(arr_x[0],arr_y[0]);
 ctx.stroke();
}
</script>
</head>
<body>
<form id = "vertex" onsubmit="draw_polygon();return false;">
  Specify the Quantity (between 1 and 999): <input type="number" name="quantity" min="1" max="999" placeholder="4">
  <input type="submit">
</form>
<canvas id="myCanvas" width="600" height="300" style="border:1px solid #c3c3c3;">
Your browser does not support the HTML5 canvas tag.
</canvas>

</body>


</html>