タグ別アーカイブ: Java

Cygwin64を試してみました。

長い間Cygwinをアップデートしていなかったので、そろそろアップデートしたいと常々思っていました。ただ、現在開発中のプログラムがあるので、アップデートすることでそれらが動かなくなったり挙動が変わると嫌なため、二の足を踏んでいたのです。

久々にCygwinのサイトを訪問してみると、以前はsetup.exeが1種類しかなかったのに、32ビット版と64ビット版の両方が公開されているではないですか! 今回は、64ビット版Cygwinを試したときに感じたことを思いつくまま書き留めることにします。

やや恐る恐るではありましたが、64ビット版のほうをダウンロードしてインストールしてみることにしました。すると、32ビット版と区別するためにC:\Cygwin64にインストールされるようになっていました(もちろん、インストール先のディレクトリは変更可能です)。

何とかなるだろうと進めると…

続きを読む

JavaでトレースログのON/OFFをコンパイル時に切り替える。

JavaでAndroidのプログラミングに関わるようになってしばらく経ちますが、そろそろトレースログのON/OFFを上手く切り替える方法が欲しくなってくるものです。ベテランのAndroidプログラマーの方に聞いたところ、if文の条件式に定数(static finalで宣言したboolean型のフィールド)を指定することでON/OFFを切り替えるのが普通だといいます。

その方法は、私なりに以下のように解釈しました。

static final boolean ENABLE_LOGS = true;

if (ENABLE_LOGS) Log.v(“tag”, “message”);

見た目はともかく、これならログを無効にしたときには、実行時のコストが完全になくなりそうです。ただ、ON/OFFを切り替えるにはソースファイルをその都度修正する必要があり、これはいただけません。

続きを読む

Javaの設計思想が少し見えてきました。

Java のコードを本格的に書き始めてまだ数日ですが、少しずつ Java の設計思想が見えてきたような気がします。

以前は一貫性のないメソッドやコレクションや配列の間の変換のやりにくさに辟易していましたが、今では、「まあこういうのもありかな」ぐらいに感じています。

結局、目的に応じて配列やコレクションの類いは使い分ける必要があるわけで、場当たり的に選択するのではなく、よく考えて適切なものを選択し、自分のコードの中で一貫性を持たせていれば大きな問題はおきないようです。

Integer などの Number から派生したクラスが、内部の状態を更新できないのは参りますが、マルチスレッドのこととか考えるとこのほうがよいのかもしれませんね。

少し、Java のことを見直しました。

らしくない。

リニューアル後のブログの記事を見たところ、Java や Android の記事はあっても C や C++ の記事がありません。以前のブログであれば、Java や Android の記事はまったくなかったので大違いです。

我ながら「らしくない」というのが率直な感想です。今後も Java や Android の記事は書いていくつもりですが、C や C++ の記事がないのは一過性のものですので、そちらを期待して来られた方はもうしばらくお待ちください。

Javaプログラマーが知らないJava言語仕様

実際のところどうなのかはわかりませんが、Java に関してタイトルのような状況があるとかないとか。以下、その内容を具体的に書いていきます。

  • ビット演算やシフト演算は C ならできるけれど Java ではできない。
  • 同じファイルの中でクラスを複数定義できない。
  • クラスに属さない列挙型は定義できない。

これらはすべて間違いなのですが、迷信的なことがまかり通っているようなのです。上記はすべて Java でできることばかりです。

少し補足すると、同じファイルの中では、public なクラスはひとつしか定義できないのであって、public ではないクラスであればいくらでも定義することができます。

列挙型は一種のクラスのようなものなのでしょうね。どのクラスにも属さない列挙型を定義できますし、結果として列挙型の定義のみを含むファイルというのもありです。

お行事のよさが好きになれない

先日から Java についての調査を始めたことを書いています。その中で感じるのは、Java というプログラミング言語の設計思想は、C や C++ とはまったく違うということです。C# なんかと比べてもやはり違います。

何が違うかというと、ひとことでいうなら、その「お行儀のよさ」です。お行儀がよいのは悪いことではありません。しかし、ときには泥臭いことに手を染めなければならないこともあるのです。そんな状況では Java お行儀のよさはデメリットにしかならないことがあります。

例えば、Java ではメソッドの結果は必ず返却値で返すことを前提としていることがあります。実際には、引数で渡したインスタンスを更新することはできますが、では int 型などのプリミティブな型の引数を更新して呼び出し側に結果を返せるかというと、それはできません。インスタンスそのものを再割り付けした結果を返すこともできません。

これが C や C++ であればポインタを使えば簡単に実現できます。C++ なら参照を使ってもよいでしょう。C# なら out を使えばやはり簡単に実現できます。ところが、Java にはそういった手段がないようなのです。

確かに、メソッドの入力を引数に集約し、出力を返却値に集約するのは正しいことです。しかし、その方法では無駄に動的なメモリ割り付けを行うことを避けられなくなります。私の目下の関心はパフォーマンスの改善にありますから、これは大問題です。

このようなお行儀のよさが随所に見られます。これは、C が「プログラマーは間違うことがないので信用する」ことを前提としているのに対し、Java が「プログラマーは馬鹿で間違いばかり犯すので信用しない」ことを前提にしているからでしょう。

パフォーマンスがそれほど大きな問題でないならそれでもよいのです。しかし、もしそうであれば私が重い腰を上げて Java に関わることなどなかったでしょう。現実には、パフォーマンスを改善するためにあらゆる手を尽くす必要がありますし、そのたびに Java の余計なお世話が行く手を阻むのです。

 

Javaについて調査中

Android アプリの開発に携わることになった関係上、Java についていろいろ調べています。大まかなことは以前から知ってはいたのですが、本格的に調べていくといろいろなことがわかってくるものです。

今後は、Java について調査したり実験した結果を自分自身の備忘録をかねて投稿していくことにします。ですので、ベテランの Java プログラマーの方々にとっては目新しい情報はないかもしれません。

現在は、Java でいかに高速なコードを書くかについて調査を行っています。というのも、現在関わっているプロジェクトが、パフォーマンスに関してかなりシビアだからです。Android ですが、実行速度がかなり要求されます。

おおざっぱに調べた感じでは…

  • Java コンパイラの静的な最適化はほとんど期待できない。
  • メソッドをインライン置換するには、private, final, static のいずれかにする。
  • 配列の範囲チェックなど、ランタイムチェックが大きなコストを払っている。

といったところでしょうか。もちろん、インスタンス生成のコストなど、Java に限らずどんな言語でも問題になる部分は上記には含んでいません。

JIT を初めとした VM の高速化についてはいろいろ語られているようですが、静的な最適化については意外に軽視されているのではないかという感が否めません。それならしそれで、腕の見せ所がいろいろあるわけで、私としてはある意味歓迎ではあるのですが。

Android アプリに挑戦

私は Java のこともあまり知らなければ Android についても素人と変わらなかったので、これまで Android のアプリ開発の仕事があったも別の担当者にまかせてきました。

ところが最近になって、そうもいってられない状況になってきました。そこで、いよいよ重い腰を上げて Android のアプリ開発に挑戦することになりました。といっても、ほとんどが OpenGL ES を使った開発になるので、典型的な Android アプリとはかなり異なるのですが、これが何とかなればあとは応用が効くはずです。

不慣れな Java についてもある程度知識を深めるとともに、いろいろな実験を行いながら、極めていけたらと考えています。やがては、Android のお仕事も安心して自分で担当できるようになることでしょう。