エイバースの中の人

iPhoneアプリとCGMサービスを作っているABARSのBLOGです。

モルフォに見るソフトウェアIPビジネス

この記事をクリップ!
ソフトウェアIPとは、ある特定の機能を持ったプログラムのことです。例えば、画像を複数入力すると動きベクトルを計算して手ぶれを補正した画像を返すプログラムや、圧縮されたJPEG画像を入れると展開された画像を取得できるプログラムなどがあります。ミドルウェアから、特定の機能だけを取り出して、単機能にしたものがソフトウェアIPだと考えるとわかりやすいです。

ソフトウェアIPのビジネスモデルは次の点が優れています。

・単機能なため顧客ごとのカスタマイズが不要
・単一製品を多くの顧客に大量に売ることができる
・一度開発してしまえば、追加の開発リソースが不要
・ソフトウェアなため在庫リスクがない
・ハードウェアIPとは異なり、不良が出た時の損害賠償リスクが低い

逆に、単機能なため、売れれば売れるほど他社に真似されやすいという問題があります。そのため、いかに他社に作れない高度なアルゴリズムを詰め込むかがポイントになります。労働集約的なSIとは対照的です。

国内では、年間出荷台数の多い電子機器がターゲット市場になります。ガラケー、スマートフォン、デジカメなどですね。実際に、モルフォの顧客を見てみます。

顧客
2011年10月期 有価証券報告書より

この3社で、売上の約66%を占めています。次に、モルフォの商品構成を見てみます。

soft_ip_list
2011年10月期 有価証券報告書より

売上構成では、手ぶれ補正のPhotoSolidがトップ、JPEGデコーダのImageSurfが二位です。モルフォは手ぶれ補正のイメージが強いですが、実はJPEGデコーダも売れ筋です。携帯のカメラの高解像度化が進んだ結果、普通のJPEGデコーダでは速度が出なくなったのだと思います。JPEGは、係数のデコードと、IDCTの2つの処理がありますが、重いのはIDCTです。普通のJPEGデコーダでは画像全部の係数を展開して、全部のブロックをIDCTしますが、JPEGは8x8ブロック単位で独立してIDCTできるため、DC係数だけをデコードしてIDCTを省略したり、係数のデコードは必要なマクロブロックまで行うけれど、IDCTは画面に表示されるブロックしか行わないというなことをしているのだと思います。H.264などの近代的なCODECはブロック相関があるからこういったことはできないので、JPEGならではですね。

soft_ip
(第8期報告書より)

モルフォの特徴として、上位2製品で売上の39.4%しかなく、比較的、分散しています。ロングテール的ですね。これは、顧客数が少なく、同じ顧客に複数の製品を売ることで売上を伸ばした結果、特定のソフトウェアIPだけが特出して売れるということが無くなったのだと思います。また、顧客との信頼関係ができた結果、顧客からの要望で新商品が作られ、ラインナップが多様化したという可能性もあります。ソフトウェアIPは、製造コストが0で、カスタマイズコストも低く、維持費もかからないため、ラインナップを増やしてもデメリットがあまり無いのも魅力です。また、同じ製品を複数の顧客に売るよりも、同じ顧客に複数の製品を売る方が簡単なので、ラインナップを意識的に増やして売上を拡大してきたのかもしれません。

モルフォは、これらのソフトウェアIPで、年間15億円近くの売り上げを上げています。利益は3億円程度。社員数が80人と多く、販管費が高いため、思ったよりも利益率が出ていない感じです。上場した結果、バックオフィスの強化が必要になって社員数が増加しているのと、成長戦略を描くためにソフトウェアIPだけでなくアプリケーションにも手を出し始めたのが利益を圧迫しています。こういった形で成長戦略を描かざるを得ないのは、ユニークなソフトウェアIPを作るというのがいかに難しいかを表しています。ビジネスモデル的には、コア部分以外のアウトソーシングによって、よりファブレス化を目指した方が手堅いのですが、そうはいかないのが上場企業ならではの大変さでしょうか。

ということで、ソフトウェアIPだけでもかなりの売上を立てることができます。ただし、そのシンプルさとビジネスモデルの優秀さゆえに、ライバルの参入も多く、IPとして差別化し続けるのが難しいです。また、アルゴリズムの出来が重要で、資本力では新製品は作れないため、イノベーションをマネージメントするという難しい問題があり、長期的に競争力を維持するのは難しいです。ある意味、製薬業界と近い感じですね。

いかに発明をマネージメントできるか。モルフォの挑戦は続きそうです。

Android NDKのライブラリへのバージョン情報の付加

この記事をクリップ!
Android NDKでShared Libraryを作る時にバージョン情報はどうやって付ければいいかを調べていたのですが、どうやらlibfoo-2.3.soのようにライブラリ名にバージョン番号を入れるのがベストなようです。

一般的なLinuxシステムでは、sonameによるバージョン管理が行われます。例えば、次のようにライブラリをビルドすると、sonameがlibmystuff.so.1のlibmystuff.so.1.0.1が出来上がります。

gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc
 
ライブラリを使用する場合は、libmystuff.soをリンクすると、シンボリックリンクを辿ってlibmystuff.so.1.0.1が見つかり、soname=libmystuff.so.1という依存関係でリンクされます。

gcc -o test1 test1.c -llibmystuff

実行時には、リンク時のsonameを元にライブラリを探索するため、libmystuff.so.2があったとしても、libmystuff.so.1が読み込まれます。(参考情報:[C/C++]Linux共有ライブラリの簡単なまとめ)

ということで、Androidでも同様に、sonameにlibmystuff.so.1のようにバージョン情報を入れたいと考えました。しかし、そもそも、Android NDKのAndroid.mkでndk-buildをするとLOCAL_MODULEに指定した名前で自動的にlib*.soというファイル名とsonameが指定されてビルドされるため、バージョン番号を指定することができません。

無難にlibfoo-2.3.soとして、loadLibrary("foo-2.3")とするという結論に落ち着きました。

ちなみに、ビルド後にsonameを書き換えるという手も考えましたが、明らかに大変そうだったので諦めました。

2011年末の株式ポートフォリオ

この記事をクリップ!
2011年ももう終わりということで、2011年末の最終的なポートフォリオをまとめてみました。今年はインフラ系で安泰かと思われていた東京電力があんなになったり、輸出産業が軒並み打撃を受けたり、オリンパスショックなど、株の世界も激動でした。そんな背景もあって、ポートフォリオも、”分散”、”好配当”、”財務良好”をテーマに組み替えています。

銘柄PERPBR配当利回り購入理由
ゲームカード・ジョイコホールディングス3.99倍0.46倍4.66%財務はほとんど現金で、高配当、優待あり、その上、人件費抑制目的で各台計数システムが急速に普及していて好業績
バンダイナムコホールディングス12.39倍1.17倍2.23%優待を入れると利回りが4%になるのと、四半期ごとの業績報告書が読んでいて面白いので
創通 10.15倍0.82倍2.35%財務鉄壁、ガンダムの版権が資産に反映されていないので、実質的なPBRはもっと低いという資産株
東映アニメーション8.69倍0.77倍1.73%膨大な数の版権が資産に反映されていないので実質的なPBRはもっと低い、親会社によるTOBの可能性、リスク要因はワンピース特需の終了
IGポート22.4倍0.45倍0%資産はほとんど現金、エヴァやナデシコなどの版権保有、版権事業だけであれば年間2億円の利益を出せる=PER6倍程度のポテンシャル、良好なキャッシュフロー
paperboy&co9.51倍3.21倍4.53%高配当、レンタルサーバなど売上が変動しにくいストック収入が魅力、リスクはPBRの高さ(高配当の裏返し)
沖縄セルラー電話 8.51倍0.95倍4.76%安定好配当、財務安定的、DocomoやKDDIなどと比べてもPERやPBRが相対的に割安、税負担が通常程度のイーアクセスと同等程度のPERで財務は圧倒的に沖縄セルラーの方がよい
東宝不動産 18.42倍0.71倍3.03%バランスシートでは224億円で計上している土地と建物の時価は699億円で実質的なPBRは0.2倍程度とかなり割安
任天堂-1.18倍0.95%3DSが400万本突破、マリオランド、マリオカート、モンハンがそれぞれ100万本突破、今年は予想外の値下げで赤字になったが来年は急速に改善すると予想
GMOインターネット9.2倍2.01倍3.46%優待を入れると利回り15%まで跳ね上がる、ドメインが独占的
MAXIS 海外株式(MSCIコクサイ)上場投信 ---日本円のインフレヘッジ用
上場インデックスファンド海外債券(Citigroup WGBI)毎月分配型---日本円のインフレヘッジ用

皆様のポートフォリオの参考になれば!

Androidの動画配信アプリまとめ

この記事をクリップ!
Androidの動画配信アプリを調査してみたのでまとめです。ざっくり調査しただけなので、間違っていたら教えて下さい。ユニークだと思った所に色をつけています。全てストリーミングによる配信です。全体的にBeeTVがユニークで、一般的なサイトは25分程度のコンテンツを210円程度で販売しているのに対して、BeeTVのみが8分程度のコンテンツを月額課金で販売しています。BeeTVは字幕モードもあったりと、携帯での視聴に特化している印象です。尚、全てのサイトは動画選択画面をWebViewで作っていました。動画の形式はH.264のプログレッシブダウンロードが多いです。FLVはDRMが必要なケースと、PCと同じフォーマットで配信する目的で使われているようです。HTTP以外のプロトコルによるライブストリーミングは使われていないようです。iOSは動画配信などのマーケットアプリを認めていないので、各社Androidに注力している印象です。

アプリ運営コンテンツ種類コンテンツ単価コンテンツ秒数OSCODEC課金方法画質シーク単位備考
MovieGate角川角川系のアニメ/ドラマ210円25分程度2.2以降FLV
(ブラウザ内)
クレジット、電子マネー1種類不明GalaxyS2だと再生が開始できなかった
ビデオマーケットビデオマーケットフジテレビ系のアニメ/ドラマ210円25分程度2.1以降H.264
(プログレッシブDL)
(別アプリ起動)
クレジット、
キャリア課金
3種類
(3G/HSPDA/Wifi)
15sec
ビデオストアTVBankTBS系のドラマ/アニメ210円(アニメ)
315円(ドラマ)
105円でHDオプション
25分程度2.2以降H.264
(プログレッシブDL)
(アプリ内View)
キャリア課金
(Docomoを除く)、
クレジット
1種類30secソフトバンクはWifiのみ
BeeTVAvex/Docomoドラマ/海外ドラマ/コミック月額315円8分程度2.1以降
(一部2.2以降)
H.264
(プログレッシブDL)
(アプリ内View)、FLV
(海外ドラマ)
キャリア課金
(SPモード)
2種類
(3G/HSPDA)
5secコミックに音声を付けて動画化した独自コンテンツあり、電車内などの音が聞けない環境用に字幕モードあり
MF+ISAOドラマ/アニメ210円25分程度2.1以降H.264
(プログレッシブDL)
(別アプリ起動)
キャリア課金(docomo/au)、
電子マネー、
クレジット
1種類15sec

オープンドア社のドコモ公式サイトの「ゲーム大集合」にてメトセライズデストラクタの配信を開始しました

この記事をクリップ!
オープンドア社のドコモ公式サイトのゲーム大集合にて、メトセライズデストラクタの配信を開始しました。



aa



ゲーム大集合は月額300円でサイト内のAndroidアプリが遊び放題になるオープンドア社のドコモ公式サイトです。有料会員であれば、誰でも無料でメトセライズデストラクタをダウンロードして遊ぶことができます。

今回、ご提供させて頂くバージョンは、Androidマーケットで公開しているメトセライズデストラクタから、オンライン機能を外し、オフラインのRPGとしてまとめたものです。一部、インタフェースのフォントのレイアウトなど、完成度が高くなるカスタマイズを行なっています。

この機会に、ぜひとも遊んでみて頂ければ幸いです。

そろそろマーケットアプリのトップにWebViewを使うのをやめたほうがいいんじゃないか

この記事をクリップ!
AndroidのDocomoMarketもビデオマーケットもM-trixMarketもMobageも全てトップ画面をWebViewで作ってHTMLを流し込む作りになっていて、もっさりしすぎているのを何とかするべきではないかと思う今日この頃です。

AndroidのWebViewはスクロールがかくかくしすぎているし、タップしてページ遷移する度に画面全部をレンダリングするので、ユーザビリティが低すぎるのです。また、画像を全てストリーミングで読み込んでくるので、毎回ロードが発生しますし、本来はコンテンツデータだけを取得すればいいところを、HTMLやCSSなども毎回読み込んでこないといけないので、細いモバイルの回線では厳しすぎます。

ということで、ゲームと同じような作りにしてしまって、データベースからHTTPで必要な情報だけを取ってきてレンダリングするのがいいと思います。こうすると、60FPSでぬるぬるスクロールできるし、通信も最低限、UIのリソース画像などはアプリ内のローカルリソースを使えるので回線を圧迫しません。また、描画にOpenGLをばりばり使えるので、今まで見たことのないようなリッチなマーケットアプリも作れます。

理想型なのが、Android4.0のYouTubeアプリです。あれは素晴らしい。さくさくスクロールするし、動画のリストをクリックしてからすぐに次の動画の再生が始まるので、どんどん次の動画を見ていきたくなります。画面内で動画を再生しながら他の動画も探せますし、この快適さはWebViewでは到達できません。



Mobageのngcoreが流行らないのは、MobageアプリをHTMLで作ってしまったからだと思います。HTMLで作ってしまったので、HTMLからngcoreを起動しないといけない。なので、HTMLゲームの方が遷移が無い分、素早く始められてしまって、どうせHTMLゲームしかしないならブラウザ版でよくてアプリを使わないという流れになってしまっています。決して、ブラウザ版の方がよいのではなくて、ngcoreのゲームの起動が面倒すぎる、遅すぎるだけです。逆に、ngcoreでMobageのポータルアプリを作ってしまって、遷移なしにngcoreのゲームが起動すれば、スマートフォン向けのソーシャルゲームはngcoreの方が流行ると思います。そうすれば、スマートフォンらしいソーシャルゲームが見えてくるんじゃないかなと思います。

更新が楽なのは分かるのですが、スマートフォンの良さを活かす意味でも、そろそろWebViewでマーケットアプリを作るのはやめたほうがいいんじゃないかと思う今日この頃です。

AndroidとiOSの開発環境を比較してみた

この記事をクリップ!
AndroidとiOSの開発環境を比較してみました。個人的に好きな方に色をつけています。

AndroidiOS解説
開発言語JavaObjectiveCJAVAはリソースの開放をGCに任せられるので楽、iOSは文字列制御だけでも複雑でretainを忘れてメモリリークが発生したりと結構大変
統合開発環境EclipseXcode開発環境は同等ですが、好みでEclipse
エミュレータ遅すぎて使えないかなり優秀Androidのエミュレータは起動だけに数分かかる上にほとんど使えないぐらい重いので実機デバッグが必須、iOSは普通の速度で動いて快適
デバッグ大変容易Androidは機種数が多すぎてメジャーなVDPだけでも4種類あってOSのverもいろいろあるので4機種程度は買わないといけない、iOSは3GSと4で検証すればほぼOK
動作速度遅い速いAndroidはGCとVMがボトルネックで速度があまり出ない、NDKを使えばiOSに近いパフォーマンスを出すことはできるが機種依存が若干不安、iOSはネイティブなので最速
UI設計コードで配置GUIで配置iOSの方がUIは楽に配置できるけどドラッグでオブジェクト間の依存関係をつないだりするのがわかりにくい、Androidは全てプログラムで制御できるのはいいけど狙ったレイアウトにするのがなかなか難しい、ゲームを作る分にはAndroidの方が楽
アプリの配布制約なし制約ありAndroidはapkファイルを配るだけでOK、iOSは事前に登録した機種にしかインストールできない上に3ヶ月ごとにプロファイルを更新してリビルドしなければ開発中のアプリは使えなくなるためアプリを自由に配布することができない、せめて1年にして欲しいです
プラットフォームアプリの開発制約なし制約ありアプリマーケットや電子書籍マーケットなど、プラットフォーム系のアプリはAndroidでは自由に作れますが、iOSでは審査で落とされることが多いです
アプリの売上まだ市場規模が小さい市場規模が大きいiOSの方が3倍程度売上が大きいです


全体的に作りやすいのはAndroidです。初めてのアプリ開発はAndroidがオススメ。ただ、アプリの売上はiOSの方が大きいのが悩ましいところですね。個人的には、Androidでプラットフォーム型のアプリを作るのが将来性があるかなと思ってます。

後、GUI系はWindowsのVisualStudioが圧倒的に作りやすいので、将来的にWindows8とWindowsPhone7が統合されると、結構いいアプリが出てくるんじゃないかなと思っています。

イラストブックプラットフォームをオープン化しました

この記事をクリップ!
本日、イラストブックをオープン化し、APIを公開しました。これにより、イラストブックのバーチャルグラフやイラストを使用したアプリやプラグイン、掲示板のCSSデザインを開発し、イラストブック内で公開できるようになります。同時に、コンテンツを公開するイラストブックマーケットと、開発情報を公開するデベロッパーポータルを開設しました。

プラットフォームの全体像は次のようになります。

api_guide_platform


具体的に、どのようなことができるようになるかは、イラストブックマーケットを参照頂ければと思います。現段階では、エイバース開発の以下の3つのコンテンツを公開しています。

・ブックマークしているイラストを使用したパズルゲーム
・BLOGに貼り付けられる新着投稿ウィジェット
・掲示板のCSSカスタマイズサンプル

当面のキラーアプリは新着投稿ウィジェットかなと考えています。これは、自分の掲示板に投稿されたイラストを、簡単に自分のホームページやBLOGに貼り付けられるものです。表示イラスト数や、イラストのサイズも指定可能です。実際に貼り付けると次のようになります。


これらは全てAPIのみを使用して開発されており、このように、自由にコンテンツを開発し、イラストブックマーケットに公開できるようにすることで、より便利なお絵かきプラットフォームの構築を目指しています。尚、アプリからのイラストの参照の許可は、掲示板単位で設定できるようになっていますので、アプリから参照されたくない場合はイラスト本体へのアクセスをブロックすることができます。

また、デベロッパーポータルでは、各種、技術的な情報を公開しています。具体的には、APIとCSSのリファレンスの参照と、コンテンツの登録とブラウザでのエディットが可能になっています。

api_guide_api


APIとしては、JSON APIとJavaScript APIの2つを公開しており、バーチャルグラフや、掲示板のフィード、ブックマーク情報などを取得可能です。また、クロスドメイン対策として、JSONPによるアクセスも提供しているため、より手軽に自分のWEBページに組み込むことが可能です。

JavaScript APIには、イラストブック関係のAPIだけでなく、ゲーム開発用の描画APIも用意しています。このAPIは、HTML5が使えるブラウザではHTML5のCanvasで、使えないブラウザではFlashCanvasを使うことで、IE/Chrome/iPad/Androidなどのデバイスの差異を吸収します。また、マウスイベントとiPadのタッチイベントも自動的にマッピングするため、1つのコードでマルチプラットフォーム展開が可能です。実際に、サンプルの15パズルは、IEとiPadを含む全てのブラウザで動作しています。

また、イラストブックにデータを保存するAPIも提供しています。このAPIはキーバリューストアになっており、ゲームのセーブデータ用に使うこともできますし、ハイスコアを登録して、アプリの設定にそのハイスコアのキーを設定するだけで、アプリプレイ画面に自動的にランキングを出すこともできます。

アプリの開発は、全てブラウザ上で行うことができます。ブラウザ上では、リッチエディタ(ACE)が利用でき、JSHintによるLintチェックも可能です。

code_editer

CSSデザインでは、要望の多かったCSSレベルでのデザインの変更に対応します。CSS構成はCSSリファレンスから参照することができます。作成したデザインは自分だけで使うこともできますし、設定一つで一般に公開して、多くの人に使ってもらうこともできます。これによって、弱かったイラストブックのデザインテンプレートを強化できればいいなと考えています。

ということで、今後とも、より柔軟で、より魅力的なお絵かきプラットフォームを目指して開発を進めていこうと考えていますので、APIともども、ぜひともご利用頂ければ幸いです。

ザッパラスの会員数減はdメニューで底打ちするかも

この記事をクリップ!
ここ最近、スマートフォンの急速な普及で、ガラケーのコンテンツプロバイダは減益が続いており冬の時代だったのですが、そろそろ風向きが良い方向に変わりそうな気がしています。

そもそもiModeで、多くのコンテンツプロバイダが上場できるくらい利益を上げられたのは、月額課金の仕組みのおかげでした。月額課金は、一度有料会員登録すると、あまり使わなくなったとしても、なかなか止められないのが特徴です。

なぜ止められないかというと、「また使うかもしれない」「セーブデータや利用履歴が蓄積していくので消えるのがもったいない」「月々の料金が数百円程度なのでわざわざ解約するのが面倒」だからです。

「また使うかもしれない」「もったいない」「捨てるのが面倒」ということで、物を捨てられない理由と同じですね。断捨離があれだけブームになるということは、それだけ捨てられない人が多いということで、同様に、ガラケーコンテンツの月額課金も止めにくいというのがあるように思います。

そして、なぜガラケーユーザがスマートフォンに買い換えると減益になるかというと、スマートフォンでは月額課金ができない(できなかった)ので、スマートフォンに買い換えた瞬間に自動的にiModeのサービスを解約させられるからです。スマートフォンへの移行に伴って自動的に毎月数万人減っていく会員数、コンテンツプロバイダには厳しい感じでした。

zap2

参考:ザッパラスさんの株価

正直、もうダメかと思われていたのですが、先月、dメニューが始まりました。これが素晴らしすぎて、従来、スマートフォンに変えると、月額課金していたサービスは全て自動的に廃止されていたのが、dメニューが始まったことで、スマートフォンに対応しているサービスであれば、自動的に引き継がれ、課金が継続されるようになりました。(マイメニュー引継ぎ対応サイトの情報提供について)どう変わったかは、ザッパラスさんの決算説明会資料が詳しいです。

zap

引用元:ザッパラスさんの決算説明会資料

今まで、自動的に解約されていたのが、自動的に引き継ぎになったんですね。これで、再び「また使うかもしれない」「もったいない」「捨てるのが面倒」という状態になったので、この状況からユーザが自分で解約まで持っていくのは結構手間です。

ということで、第三四半期から、会員数の減少は底打ちし、意外とコンテンツメーカも復活してくるんじゃないかなという気がしています。

最後に、モバイル業界別に今後の予想をまとめてみます。

業種商品〜2011年11月2011年12月〜
コンテンツプロバイダ(WEB)占いとか苦しい持ち直し?
コンテンツプロバイダ(電子書籍)コミックとか苦しい持ち直し?
コンテンツプロバイダ(ゲーム)JAVAアプリとか苦しい移植コストがかかるのでまだ少し苦しい
コンテンツプロバイダ(SNS)SNS向けゲームとか好調PCを考えなくていいのでHTML5への移行は意外と問題無く進み好調継続
ミドルウェアベンダーOS、ブラウザとか苦しいガラケー出荷数減が続きさらに苦しい

AppEngineでmemcacheリクエストをまとめて発行する

この記事をクリップ!
memcacheのgetを10回とか連続で行った場合、各getが前のgetの終了を待機するのでオーバヘッドが大きいです。そういう時は、memcache.get_multiがオススメです。

例えば、複数のgetをしてディレクトリに格納するコード
dic=[]
dic["id1"]=memcache.get("id1")
dic["id2"]=memcache.get("id2")
dic["id3"]=memcache.get("id3")
は、次のように書けます。
key_list=["id1","id2","id3"]
dic=memcache.get_multi(key_list,key_prefix="")

key_prefixには、各キーの先頭に付ける文字列を指定することができます。指定した場合でも、返り値のディレクトリのキーにはプリフィックスは付きません。便利です。

このget_multiはかなり高速で、10回分のgetでも、2回分程度のgetと同じ時間で処理してくれます。記事の一覧の取得など、記事単位でキャッシュしている場合は、get_multiでまとめて取ってくるのがオススメです。

AppEngineでデータストアアクセス無しでReferencePropertyのKey値を取得する方法

この記事をクリップ!
ReferencePropertyを持つdb.Modelがあったとします。
class MesThread(db.Model):
 bbs = db.ReferenceProperty(Bbs)

キャッシュ処理などで、データは不要でキーだけが欲しい場合に、thread.bbs.key()としてしまうと、bbsのデータストアアクセスが発生してしまいます。同様に、if(thread.bbs)のような処理でも、データストアアクセスが発生します。

これは、次のように記述することで、データストアアクセスを回避してdb.Keyを取得することができます。
bbs_key=MesThread.bbs.get_value_for_datastore(thread)

また、queryを作る際も、MesThread.all()ではなく、次のように記述することでキー値だけを取得することができます。高速化に便利です。
query = db.Query(MesThread,keys_only=True)

AppEngineにおけるputのフックとキャッシュコントロール

この記事をクリップ!
データストアのgetは遅いのでmemcacheを利用してキャッシュしようとした場合に、キャッシュの無効化をどのように実装すればよいのか迷うことがあります。

例えば、あるthreadオブジェクトがあって、あるタイミングで24時間キャッシュし、別のタイミングでキャッシュから読み込んだとします。
TimeA : memcache.put("id",thread,60*60*24)
TimeB : thread=memcache.get("id")

キャッシュから読み込んだ際にthreadが更新されていなければ問題は置きません。しかし、threadが更新されていた場合に、キャッシュを無効化していなければ、24時間の間、古いデータが表示されてしまいます。

これを解決する一番簡単な方法は、thread.put()をしている場所でdeleteを入れてしまうことです。しかし、これだと、put()している全ての場所にdeleteを入れる必要があり、大変面倒です。
thread.put()
memcache.delete("id")


ということで、次のようにputをフックするのがオススメです。thread.put()が呼ばれると自動的にmemcache.deleteが呼ばれます。
class Thread(db.Model):
 data_member=db.StringProperty()

 def put(self,**kwargs):
  super(Thread, self).put(**kwargs)
  memcache.delete("id")


また、AppEngineは全てのオブジェクトに独立したキーが与えられます。次のように、キーにプリフィックスをつけた形でそのまま使って格納すると管理が楽です。PREFIXを付けておくことで、PREFIXの名前でバージョン管理ができます。
TimingA : memcache.get(PREFIX+str(thread.key()))
HookedPut : memcache.delete(PREFIX+str(thread.key()))


イラストブックのお絵かき掲示板では、10個のイラストを1ページで表示するのですが、イラストのオブジェクトを全てこの方法でキャッシュすることによって、1200msかかっていた処理が600msまで短縮されました。

ちなみにAppEngineのmemcacheにはdb.Modelをそのまま突っ込めます。データへのキーではなく、ちゃんとデータで保存されるので、memcache.getした後にそのdb.Modelにアクセスしても、db.getは発生しません。(AppStatsで確認しました)

AppEngineは11月7日から新料金体系になるので、memcacheでキャッシュしまくるのがオススメです。

AndroidのNDKでNEONを使った場合にJavaの浮動小数変数が破壊される問題への対策

この記事をクリップ!
AndroidのNDKでNEONを使っていて、Javaのdoubleと混載した場合に、doubleの変数が破壊されたので調べてみました。まず、NEONのレジスタのd8-d15がFPUと共有されていて、このレジスタの退避ルールはcallee savedで、関数の呼びだされ側、つまりNDKのコード側で退避しなければならないようです。


I’ve only used assembly programming so far, so I will generally describe techniques under assembly terms, but everything should be equally applicable when programming with intrinsics, just with a different syntax. There is one important thing, however, which is applicable only when you program in assembly (you don’t have to worry about that when using intrinsics): make sure you save and restore d8 to d15 if you use them in your function, as the ABI specifies that these registers must be preserved by function calls. If you don’t, it may work fine for a while, until you realize with horror that the floating-point variables in the calling functions become corrupted, and all hell breaks loose. So make sure these registers are saved and restored if they are used.
引用:Introduction to NEON on iPhone


上記にはintrinsicで書かれていれば特に気にしなくても問題無い(コンパイラが自動的にケアする)と書かれていて、実際にiOSでは問題が出ないのですが、Android環境では問題が出ていて、オブジェクトファイルを逆アセンブルしてみても退避コードが生成されていないです。(GCCは4.5.3を使っています)

ちなみにVP8では自前で退避しているようです。


Regarding to your question on
#if HAVE_ARMV7
void vp8_push_neon(INT64 *store);
void vp8_pop_neon(INT64 *store);
#endif
this code is written for ARM7 NEON. For ARM NEON, d8-d15 are
callee-saved registers. vp8_push_neon() saves d8-d15 values before
going into decoding, and vp8_pop_neon() restores those saved values
after decoding is done. The prevents problem when these registers are
used in user application and their values need to be preserved before
and after the decoding. For example, if you measure time before and
after the decoding for testing performance, the beginning time needs
to be preserved, which is floating-point number and can be in d8-d15.
Therefore, d8-d15 values have to be stored to make it right.
引用:Some questions about VP8 decoder assembly functions


ということで、次のようなコードでNEONを使う関数を囲むことで、レジスタを退避してみました。

#define PUSH_NEON if(check_neon()){asm("vpush {d8-d15}");}
#define POP_NEON if(check_neon()){asm("vpop {d8-d15}");}

結果、JAVA側のdoubleの変数が破壊されなくなったので、やはりレジスタの退避はうまくいってなかったようです。

推測するに、JNIを使うとmain関数が無いため、コンパイラがvpushを入れる場所を上層へ押し込んでいった結果、最後まで入れられなかったのかなと考えています。iOSの場合は、スタティックライブラリなので、コンパイラが自動的に入れられた予感です。

AppEngineにおけるReferencePropertyのListの正しい記述法

この記事をクリップ!
AppEngineで、とある1データへの参照は
 class MesThread(db.Model):
  bbs_ref = db.ReferenceProperty(Bbs)
のように書けるので特に問題無いのですが、1データではなく複数データへマッピングしたい場合は、ReferenceListPropertyが存在しないため、定義の仕方を考える必要があります。

ぱっと思いつくのは、
bbs_list = db.StringListProperty()
のように、文字列のリストを定義しておいて、str(bbs.key())のようにデータのキーを文字列化して入れることです。これだと、とりあえずは動いてしまうのですが、問題があります。

例えば、直近の話題としては、Python2.7がM/Sデータストアで提供されないため、HRDデータストアへの移行が必要ですが、移行をするとキー値が変化してしまいます。Googleの提供するM/S型データストアからHRDデータストアの移行ツールでは、ReferencePropertyのキー値の自動変換をしてくれますが、StringListPropertyは変換してくれません。

ということで正解は、
bbs_key_list = db.ListProperty(db.Key)
のように、db.Keyのリストを定義しておいて、db.Key(str(bbs.key()))のようにデータのキー値をdb.Key型に変換して入れておくことです。こうすると、HRDデータストアの移行ツールで認識して、自動でキー値を書き換えてくれます。今回のHRDへの移行のように、可能性としてはデータセンターの統廃合とかでもキー値が変わることは有り得そうな気がするので、できるだけこの形で格納しておくとよいようです。

iOS5でOnTouchStartイベントが来ない場合の対処法

この記事をクリップ!
iOS4のMobileSafariでは問題無く来るOnTouchStartイベントがiOS5では来ないケースがあったので検証ページを作りました。まとめると、次のようになりました。

iOS4iOS5
divにOnTouchStartを設定OKOK
divにOnMouseDownを設定OKOK
innerHTML内にOnTouchStartを含むdivを動的に作成OKNG
innerHTML内にOnMouseDownを含むdivを動的に作成OKOK

innerHTMLで動的にdivを作る場合で、そのdivにOnTouchStartイベントを登録した場合のみ動作しません。OnMouseDownではOKなのでMobileSafariのバグな気がします。JQueryでもこれが原因でButtonが動作しない問題があるようです。

いろいろ試してみた結果、対処法としては、
 document.getElementById("div_id").innerHTML="<div ontouchstart="alert('hoge');"></div>";
と書かずに
 document.getElementById("div_id").innerHTML="<div id='hoge1'></div>";
 document.getElementById("hoge1").addEventListener("touchstart",function(){alert('hoge');},false);
のように、一度innerHTMLにdivを作った後に、遅延してaddEventListenerをすれば回避できるようです。

イラストブックにiPadから絵を投稿できる機能を追加しました

この記事をクリップ!
無料レンタルお絵描き掲示板のイラストブックに、iPadからイラストを投稿したり、絵で返信できたりすることのできる機能を追加しました。iPadから”イラストを描く”を選択すると、自動的にHTML5版の簡易お絵かきツールが立ち上がります。これによって、より気軽にイラストコミュニケーションを楽しむことができます。また、iPadから投稿できる初のお絵描き掲示板になります。



PCから使ってみる場合は、お絵かきページのURLにipad=1を追加することでお試しすることもできます。

PCからiPad版を触ってみる(要HTML5対応ブラウザ)

2日で作ったのでかなり機能は制限されていますが、それなりに遊べると思うのでぜひどうぞ。

メトセライズデストラクタ mixiアプリ版 運営終了のお知らせ

この記事をクリップ!
2年近く運営してきたメトセライズデストラクタmixiアプリ版ですが、2011年11月11日(金)をもって運営を終了することとなりました。長らくご愛顧頂きましてどうもありがとうございました。尚、mixiアプリ版からMMO版へのセーブデータの移行はMMO版のアカウントページから行うことができますので、ご活用頂ければと思います。

メトセライズデストラクタmixiアプリ版は、いろいろありましたが、他社のプラットフォームにアプリを出すといういい経験ができたと思っています。運営停止の理由は、mixi側のAPI変更に伴うアプリの改修のコストが大きくなってきたためです。自社プラットフォームであれば一度作ってしまえば、運営を続けるコストはそんなに大きくないのですが、他社プラットフォームの場合、他社プラットフォームの仕様変更に合わせてアプリ側のプログラムも書き換えないといけないというのがコスト高の要因です。また、一番の魅力であったアプリへの動線も、その他カテゴリへの割り当てによって無くなってしまったので、改修するコストに見合った効果は得られないと判断しました。

今後は、スマートフォン向けのアプリと、自社プラットフォームの構築に開発リソースを割いていく予定です。

最後になりましたが、メトセライズデストラクタmixiアプリ版を遊んで頂き、本当にどうもありがとうございました。今後とも、エイバースをよろしくお願いいたします。

AndroidNDKとiOSでライブラリを作る際に不要なシンボルをエクスポートしない方法

この記事をクリップ!
AndroidやiOSではライブラリを作ることができます。例えばAndroidではAndroidNDKを使用してC++のソースから.soファイルを作成します。(NDKの使用方法)

NDKでライブラリを作る場合:

コンパイル方法
(1)jniフォルダにC++ソースとmakeファイルを置く
(2)ndk-buildコマンドを実行
(3)libsフォルダに.soが出来る

インタフェース用の.javaを作成
(1)System.loadLibrary("library_name");と記述
(2)C++で記述したものと同じ引数を持つ関数をnative指定で記述


NDKで作ったライブラリを使う場合:

.soと.javaをプロジェクトのlibsフォルダとsrcフォルダにコピー
javaの関数を呼ぶとJava_*というC++の関数が呼ばれる


また、iOSの場合はXcodeの”プロジェクトの新規作成”からStaticLibraryを選択することでスタティックライブラリのプロジェクトを作成することができます。このプロジェクトでコンパイルするとスタティックライブラリである.aファイルが作成されます。ただし、iOSはシミュレータ用にはi386命令、実機用にはarm命令でコンパイルする必要があります。そこで、ビルドターゲットをプロジェクト内で複製し、シミュレータ用とARM用にそれぞれビルド、Lipoで結合してユニバーサルバイナリにします。


lipo -create "DerivedData/test/Build/Products/Release-iphoneos-iphone/test.a" "DerivedData/test/Build/Products/Release-iphonesimulator-simulater/test.a" -output "test.a"


スタティックライブラリを使う場合は、作成したユニバーサルバイナリのtest.aとインタフェースを記述した.hをプロジェクトに追加すればよいです。

しかし、このままだと、Android/iOS共に、関数名や構造体名がだだ漏れになります。試しに.soや.aをテキストエディタで開いてみると、関数名が含まれていることが分かります。このようなライブラリをそのまま配布すると、知られたくない設計情報を解析することが可能になってしまいます。そこで、このような不要なシンボルをエクスポートしない方法を考えます。

Androidの場合は比較的簡単です。gccのビルドオプションに-fvisibility=hiddenを付けると、不要なシンボルはエクスポートされなくなります。エクスポートしたい関数にだけ

 __attribute__((visibility("default")))

を付けます。

 __attribute__((visibility("default"))) JNIEXPORT jint JNICALL Java_abars_test_CreateInstance(JNIEnv *env, jclass obj, jstring filename)

みたいな感じです。

ここまではいいんですが、iOSではこのオプションが使えません。というのも.aはオブジェクトファイルを結合しただけの形式だからです。従って、リンク時に有効な-fvisibilityは無効で、有効な解決策はありません。単純なライブラリであれば、無名名前空間に隠したい関数を全て入れてしまえばよいですが、テンプレートを使っているとうまくいきません。

ということで、結論としてはiOSではシンボルを隠せません。妥当な解決策としては、適当なスクリプトをperlとかで書いて、関数名とクラス名を正規表現で列挙し、ClassNo1とかfunc_no1とか適当なものに置換するぐらいです。

aa3


気合で置換するとこんな感じになります。将来的にはiOSでダイナミックリンクライブラリをサポートして欲しいですね。

まことじさんによるイラストブック紹介漫画を公開しました

この記事をクリップ!
aa


イラストブックの宣伝活動ということで、イラストブックの紹介漫画を作成しました!イラストブックの使い方ページから読むことができます。作者はまことじさんです。素敵な仕上がりになっていますので、ぜひぜひどうぞ。

ニコニコ動画の再生数とコメント数の推移を自動的に集計

この記事をクリップ!
tracker


ニコニコ動画の再生数とコメント数の推移を自動的に集計するサービス「ニコニコトラッカー」を公開しました!URLを入力すると集計を開始し、毎日自動的に再生数とコメント数を記録、グラフ化することができます。広告効果の測定や、曜日や時期による影響など、アクセス解析にご利用頂ければと思います。
Search
Profile
Twitter
TopHatenar
HotEntry
Counter

アクセス解析付きカウンター。あなたのBLOGにもどうですか?登録はこちらから。

TOP/ BLOG/ LECTURE/ ONLINE/ RUINA/ ADDON/ THREAD/ METHUSELAYZE/ IPHONE/ MET_IPHONE/ ENGLISH/ RANKING
  • ライブドアブログ