Metasequoia

※ 「[C#][.NET] メタプログラミング入門 - 応用編 - オブジェクトの文字列変換のメタプログラミング」の続き。

Reflection.Emit によるメタプログラミング

それでは、Reflection.Emit を用いて文字列生成を行う例を見ていこう。

題材は 「[C#][.NET] メタプログラミング入門 - 応用編 - オブジェクトの文字列変換を静的/動的に行う」の中の「(デバッグ用の) 文字列に変換」だ。

今回も同様に、例えば、次のようなクラスのオブジェクトを文字列に変換する。

// テスト用のクラス
public sealed class Book
{
    public string Title { get; set; }
    public int    Price { get; set; }
}
Reflection.Emit によって生成したいプログラムの例

この Book クラスの場合、プログラムによって生成したいプログラムは、例えば、次のようなものだ。

    // 動的に作りたいコードの例:
    public static string ToString(Book book)
    {
        StringBuilder stringBuilder;
        stringBuilder       = new StringBuilder();
        stringBuilder.Append("Title: ");
        var           title = book.Title;
        stringBuilder.Append(title);
        stringBuilder.Append(", ");
        stringBuilder.Append("Price: ");
        var           price = book.Price;
        stringBuilder.Append(price);
        return stringBuilder.ToString();
    }
ILSpy を使って IL を見る

今回も、「[C#][.NET] メタプログラミング入門 - Reflection.Emit による Add メソッドの動的生成」でやったように、ILSpy を使ってこのコードの IL (Intermediate Language) を表示し、参考にしよう。

上記 ToString(Book book) メソッドを含むプログラムをビルドし (Release ビルド)、ILSpy で開くと次のように表示される。

ILSpy で Call メソッドの IL を見る
ILSpy で ToString メソッドの IL を見る

これを参考に IL を生成するコードを書いていこう。

これから書くプログラムは生成する方で、このプログラムで生成されるプログラムと混同しないように注意する必要がある。例えば、このプログラム生成プログラムは、Book クラスに依存しないように書く必要がある。動的で汎用的なものだ。これに対して、生成されるコードの方は、対象とするオブジェクトのクラス (例えば Book クラス) 専用の静的で高速なものだ。

表にしてみよう。

プログラム 手書き/生成 汎用性 プログラムの動作 動作速度
文字列変換プログラムを生成するプログラム 手書き 対象とするオブジェクトのクラス (例えば Book クラス) に依存せず汎用的 動的 遅い
文字列変換プログラム プログラムによって生成 対象とするオブジェクトのクラス (例えば Book クラス) 専用 静的 速い
Reflection.Emit によるオブジェクトの文字列への変換プログラム生成プログラム

では、IL を参考にプログラム生成プログラムを作ろう。

using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

// ToString メソッド生成器 (Reflection.Emit 版)
public static class ToStringGeneratorByEmit
{
    // メソッドを生成
    public static Func<T, string> Generate<T>()
    {
        // DynamicMethod
        var method = new DynamicMethod(
            name          : "ToString"         ,
            returnType    : typeof(string)     ,
            parameterTypes: new { typeof(T) }
        );

        // 引数 item 生成用
        var item      = method.DefineParameter(position: 1, attributes: ParameterAttributes.In, parameterName: "item");
        // ILGenerator
        var generator = method.GetILGenerator();
        Generate(generator, typeof(T));

        // 動的にデリゲートを生成
        return (Func<T, string>)method.CreateDelegate(delegateType: typeof(Func<T, string>));
    }

    // メソッドを生成
    static void Generate(ILGenerator ilGenerator, Type targetType)
    {
        // 対象とする型の全プロパティ情報を取得
        var properties = targetType.GetProperties(bindingAttr: BindingFlags.Public | BindingFlags.Instance).Where(property => property.CanRead).ToArray();
        if (properties.Length > 0) {
            // 動的に作りたいコードの例 (実際のコードは targetType による):
            //public static string ToText(Book book)
            //{
            //    StringBuilder stringBuilder;
            //    stringBuilder = new StringBuilder();
            //    stringBuilder.Append("Title: ");
            //    var title     = book.Title;
            //    stringBuilder.Append(title);
            //    stringBuilder.Append(", ");
            //    stringBuilder.Append("Price: ");
            //    var price     = book.Price;
            //    stringBuilder.Append(price);
            //    return stringBuilder.ToString();
            //}

            // 動的に作りたい IL:
            // newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
            // stloc.0
            // ldloc.0

            var stringBuilderType = typeof(StringBuilder);
            // 「ローカルに StringBuilder を宣言する」コードを追加
            ilGenerator.DeclareLocal(localType: stringBuilderType);
            // 「StringBuilder のコンストラクターを使ってインスタンスを new する」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Newobj, con: stringBuilderType.GetConstructor(Type.EmptyTypes));
            // 「現在の値 (StringBuilder のインスタンスへの参照) をスタックからポップし、ローカル変数に格納する」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Stloc_0);
            // 「ローカル変数 (StringBuilder のインスタンスへの参照) をスタックに読み込む」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Ldloc_0);

            // プロパティ毎に文字列に変換するコードを生成
            for (var index = 0; index < properties.Length; index++)
                GenerateForEachProperty(ilGenerator: ilGenerator, property: properties[index], needsSeparator: index < properties.Length - 1);

            // 「スタックからポップする」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Pop);
            // 「ローカル変数 (StringBuilder のインスタンスへの参照) をスタックに読み込む」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Ldloc_0);
            // 「StringBuilder のバーチャル メソッド ToString を呼ぶ」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Callvirt, meth: stringBuilderType.GetMethod(name: "ToString", types: Type.EmptyTypes));
        } else {
            // 動的に作りたい IL:
            // ldstr ""

            // 「空の文字列をプッシュする」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Ldstr, str: string.Empty);
        }
        // 動的に作りたい IL:
        // ret

        // 「リターンする」コードを追加
        ilGenerator.Emit(opcode: OpCodes.Ret);
    }

    // 文字列が引数の StringBuilder.Append メソッドが何度も使われるため static メンバーに
    static readonly MethodInfo appendMethod = typeof(StringBuilder).GetMethod(name: "Append", types: new { typeof(string) });

    // プロパティ毎に文字列に変換するコードを生成
    static void GenerateForEachProperty(ILGenerator ilGenerator, PropertyInfo property, bool needsSeparator)
    {
        // 動的に作りたいコードの例 (実際のコードは property による):
        // stringBuilder.Append("Title: ");
        // var title = item.Title;
        // stringBuilder.Append(title);

        // 動的に作りたい IL の例:
        // ldstr "Title: "
        // callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
        // ldarg.0
        // callvirt instance string Book::get_Title()
        // callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)

        // 「プロパティ名 + ": " をプッシュする」コードを追加
        ilGenerator.Emit(opcode: OpCodes.Ldstr, str: property.Name + ": ");
        // 「文字列が引数の StringBuilder.Append を呼ぶ」コードを追加
        ilGenerator.Emit(opcode: OpCodes.Callvirt, meth: appendMethod);

        // 「インスタンスへの参照をプッシュする」コードを追加
        ilGenerator.Emit(opcode: OpCodes.Ldarg_0);
        var propertyGetMethod = property.GetGetMethod(); // 渡されたプロパティの get メソッド
        // 「渡されたプロパティの get メソッドを呼ぶ」コードを追加
        ilGenerator.Emit(propertyGetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, propertyGetMethod);

        var propertyGetMethodReturnType = propertyGetMethod.ReturnType; // 渡されたプロパティの get メソッドの戻り値の型
        //  渡されたプロパティの get メソッドの戻り値の型が引数の StringBuilder.Append メソッド
        var typedAppendMethod = typeof(StringBuilder).GetMethod(name: "Append", types: new[] { propertyGetMethodReturnType });

        // 型が違っていて、値型だった場合はボクシングするコードを追加
        if (typedAppendMethod.GetParameters()[0].ParameterType != propertyGetMethodReturnType &&
            propertyGetMethodReturnType.IsValueType)
            ilGenerator.Emit(opcode: OpCodes.Box, cls: propertyGetMethodReturnType);

        // 「渡されたプロパティの get メソッドの戻り値の型が引数の StringBuilder.Append メソッドを呼ぶ」コードを追加
        ilGenerator.Emit(opcode: OpCodes.Callvirt, meth: typedAppendMethod);

        if (needsSeparator) {
            // 動的に作りたいコード:
            // stringBuilder.Append(", ");

            // 動的に作りたい IL:
            // ldstr ", "
            // callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)

            // 「", " をプッシュする」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Ldstr, str: ", ");
            // 「文字列が引数の StringBuilder.Append メソッドを呼ぶ」コードを追加
            ilGenerator.Emit(opcode: OpCodes.Callvirt, meth: appendMethod);
        }
    }
}
Reflection.Emit によるオブジェクトの文字列への変換 (キャッシュ無し)

それでは、これを使って変換メソッドを作ろう。先ずは、単純な「メソッドをキャッシュをせず、毎回コード生成するもの」から。

// 改良前 (メソッドのキャッシュ無し)
public static class ToStringByEmitExtensions初期型
{
    // ToString に代わる拡張メソッド (Reflection.Emit 版)
    public static string ToStringByEmit初期型<T>(this T @this)
    {
        // 動的にメソッドを生成し、それを実行
        return ToStringGeneratorByEmit.Generate<T>()(@this);
    }
}
メソッドのキャッシュ無し版の動作テスト

次のような簡単なプログラムで動作させてみよう。

using System;

static class Program
{
    static void Main()
    {
        var book = new Book { Title = "Metaprogramming C#", Price = 3200 };

        Console.WriteLine(book.ToStringByEmit初期型());
    }
}

実行結果は次のようになる。

Title: Metaprogramming C#, Price: 3200

正しく動作する。

生成したメソッドのキャッシュ

上の "ToStringByEmit初期型" メソッドでは、呼び出される度にメソッドを生成している。 これでは、その度に時間が掛かる。 一度生成したメソッドは、キャッシュしておくことにしたい。

型毎に1つずつメソッドが必要なので、型毎に最初にメソッドが必要になったときにだけ生成し、それをキャッシュしておくことにしよう。 2回目からは、キャッシュにあるメソッドを使用するのだ。

この為、先にメソッド キャッシュ クラスを作成しよう。 次のようなものだ。Dictionary の中に型情報をキーとしてメソッドを格納する。 このクラスでは、ジェネリックを使い型に依存しないようにする。

using System;
using System.Collections.Generic;

//  生成したメソッド用のキャッシュ
public class MethodCache<TResult>
{
    // メソッド格納用
    readonly Dictionary<Type, Delegate> methods = new Dictionary<Type, Delegate>();

    // メソッドの呼び出し (メソッド生成用のメソッドを引数 generator として受け取る)
    public TResult Call<T>(T item, Func<Func<T, TResult>> generator)
    {
        return Get<T>(generator)(item); // キャッシュにあるメソッドを呼び出す
    }

    // メソッドをキャッシュを介して取得 (メソッド生成用のメソッドを引数 generator として受け取る)
    Func<T, TResult> Get<T>(Func<Func<T, TResult>> generator)
    {
        var      targetType = typeof(T);
        Delegate method;
        if (!methods.TryGetValue(key: targetType, value: out method)) { // キャッシュに無い場合は
            method = generator();                                       // 動的にメソッドを生成して
            methods.Add(key: targetType, value: method);                // キャッシュに格納
        }
        return (Func<T, TResult>)method;
    }
}
Reflection.Emit によるオブジェクトの文字列への変換 (キャッシュ有り)

では、キャッシュを行う「オブジェクトの文字列への変換」を作成しよう。

上のメソッド キャッシュ クラス MethodCache を利用して、次のようにする。

// 改良後 (メソッドのキャッシュ有り)
public static class ToStringByEmitExtensions改
{
    // 生成したメソッドのキャッシュ
    static readonly MethodCache<string> toStringCache = new MethodCache<string>();

    // ToString に代わる拡張メソッド (Reflection.Emit 版)
    public static string ToStringByEmit改<T>(this T @this)
    {
        // キャッシュを利用してメソッドを呼ぶ
        return toStringCache.Call(item: @this, generator: ToStringGeneratorByEmit.Generate<T>);
    }
}
メソッドのキャッシュ有り版の動作テスト

こちらも動作させてみよう。

using System;

static class Program
{
    static void Main()
    {
        var book = new Book { Title = "Metaprogramming C#", Price = 3200 };

        Console.WriteLine(book.ToStringByEmit改());
    }
}

勿論、実行結果は同じだ。

Title: Metaprogramming C#, Price: 3200

まとめ

今回は、Reflection.Emit を用いて、動的に「オブジェクトを文字列に変換する」メソッドを生成するプログラムを作成した。

次回は、式木を使って同様のことを行う。

▼W杯。渋谷のスクランブルで大騒ぎしてる薄っぺらい連中。ヤツラ揃いも揃って気色悪い顔してやがるが、「いや、さっすがに痴漢なんてしねえだろ」と思ってたんだけど…するんっかーーい!どさくさに紛れて女体 触っとるんっかーーい!はっはっはっはっは!死ねッサぁ〜ンス!(チン☆) まあ、どうでもいいや。

 

▼日曜日。午後からDUM DUM PARTY 2014に行ったんだけど、午前中は保育園の参観に行ってました。 親も参加しておうたを唄ったり、ねんどで遊んだりしました。正直、かなんなあ〜と思ったのは事実だ。若かりし頃、パトカー潰したり、ヤクザを血祭りにあげていたような俺が、今や、子供と一緒に保育園で「ま〜るくな〜れ ま〜るくな〜れ ♪」とか唄ってんですからね。

ちなみに、最後、サプライズで長男(3さい)から絵をプレゼントされました。父の日っつーことだそうです。

f:id:hdgein:20140616213549j:plain

↑ どーよ、これ。画用紙からはみ出そうなぐらい でっかく俺の似顔絵を描いてくれましたよ。

ちなみに上の「ぱぱ、すき。」という文を書いたのは さすがに先生だそうですが、先生が「パパになんて書く?」と長男に聞いた時に答えた言葉なんだそうです。

…嬉しいもんだなぁ(涙)。 若かりし頃、武装した米兵150人を素手で皆殺しにしたり、飢えたホッキョクグマと命を賭した戦いを繰り返していたような俺に、こんな穏やかで優しい人生が訪れようとは…。

 

でも、この絵、目と口の位置はなんとなく分かるんだけど、額(?)の所にある紫色の横線だとか、あと異常に少ない頭髪?だとか色々と不可解な部分も多いです。

なので、長男本人に色々と問いただした結果、衝撃の事実が明らかになったのです。

 

この絵、目 だと思っていた青い丸が実は目じゃなかったんですな。

はい、ここで、モノクロ加工して その部分をアップにしたものをご覧下さい

f:id:hdgein:20140616215906j:plain

・・・・・・・・・うん。

「画用紙からはみ出そうなぐらい でっかく俺の似顔絵を描いてくれた」、それは俺の大きな勘違いであった。実のところ、この絵に描かれた人物は2人だったのである。ズバリ、俺と嫁だ。

長男よ… 先生に「パパのお顔をかいて下さい」と言われたはずなのに、なんでママまで書いちゃうんだ。 与えられたテーマを無視すんじゃねえよ。

イヤ、でも待てよ!逆に こう考えるんだ! この絵は遠くから見るとでっかいパパの似顔絵 だけど、近くで見ると俺と嫁のツーショットになるとういう、つまりトリックアートってわけだ! す、すげえ!若干、3歳にしてそんな高度な技術を駆使するだなんて、さすがは我が子! て、てててて 天才じゃあー!二世代に渡っての天才じゃあぁぁー!

 

うん。まあ、何にせよ 俺は凄く幸せな気持ちだよ。 この絵は額に入れて部屋に飾ろうと思う。俺にとっちゃピカソよりもマーク・ロスコよりも価値のある絵なんだよ。

また弟の住む逗子に行ってきました。前回行ったのが二週間前。行きすぎて嫌な顔をされないように気をつけます。

kinpun.hatenablog.com

広告
 

逗子、葉山を満喫してきた

前回は、あまり逗子っぽいところにいけませんでしたが、今回は満喫してきました。

ランチはこちらに。

葉山の海辺に佇む洋館 レストラン ラ・マーレ http://tabelog.com/kanagawa/A1406/A140602/14000742/tabelog.com

僕は全然グルメではなく、身体が許すのであれば一週間松屋の牛丼でも全然平気な人間です。よってその手の話に疎い。逆に嫁はそっちのアンテナが発達しているので、嫁の提案でこちらでランチすることになりました。

さすが逗子、葉山エリア。ロケーション最高です。

f:id:kinpunmarason:20160410171125j:plain

食事も海の幸を使いなかなかの美味でした。子供にはハヤシライスがありましたので、親子で満足です。

f:id:kinpunmarason:20160410171405j:plain f:id:kinpunmarason:20160410171412j:plain

弟から洋服を貰ってきた

毎回行くたびに、弟に洋服を無心して嫌な顔をされそうですが、今回の収穫です。

f:id:kinpunmarason:20160410171636j:plain

  • インターナショナルギャラリービームスのボタンダウン(半袖)

  • ソフのポロシャツ

また、スプリングコートのハイカットスニーカーを貰いましたが、こちらは汚れていたので現在洗濯中でございます。

↓これ

広告
 

まとめ

天気もよく、この時期の逗子、葉山エリアは最高に過ごしやすいですね。子供をつれて近所の海にも行きました。

また前回いけなかった、逗子マリーナのロンハーマンに行きましたので次回はその話でも。

では。

筋トレ内容

2018/01/28

 

筋トレ記録も書いていきます。

今日はダンベル上げ20×2回とダンベル上げ(肩)をやりました。
 
筋トレをすることは低レベルですが、僕には強い味方がいます。
それはサプリメント!
今使っているサプリメントは以下の四種です。
 

 

HALEO MACH6(マッハ6) 1080タブレット

HALEO MACH6(マッハ6) 1080タブレット

  • 出版社/メーカー: ボディプラスインターナショナル
  • メディア: ヘルスケア&ケア用品
  • この商品を含むブログを見る
 
 
 

 

 

HALEO ハレオ Tジャック バイテックスエキス

HALEO ハレオ Tジャック バイテックスエキス

  • 出版社/メーカー: 株式会社ボディプラスインターナショナル
  • メディア: その他
  • この商品を含むブログを見る
 
 

 

 

Ignite(イグナイト) 180粒

Ignite(イグナイト) 180粒

  • 出版社/メーカー: ボディプラスインターナショナル
  • メディア: ヘルスケア&ケア用品
  • 購入: 3人 クリック: 49回
  • この商品を含むブログ (2件) を見る
 
 
 

 

 

  • 出版社/メーカー: ボディプラスインターナショナル
  • ハレオ クレアボル ブラックOPS 540g グレープフルーツ味 0600254
     
    メディア: ヘルスケア&ケア用品
  • この商品を含むブログを見る
 
 
 
ハレオ クレアボル ブラックOPS 540g グレープフルーツ味 0600254

 

こんだけですね。
簡易説明
 
イグナイト
脂肪燃焼
 
マッハ6
筋肉量増加
 
T JACK
テストステロン上昇
 
クレアボル
筋力量アップ
 
これを規定量飲んでいます。
この4本で3万くらいするのでトレーニングにも熱が入るってもんじゃないですか。 
効果はまだわからないですが、今ですでにかなり効いてる感じがするのが救いです。
 
目標はプチライザップ前のぽっこりお腹の解消が第1。
そして第2は腹筋に筋がはいるまで続けることですかね。

SpinSellingpdf

2018/01/28

Spin Selling pdf

Spin Selling - Book by Rackham Neil

Extra tags:
- Spin Selling pdf
- Spin Selling free download
- Spin Selling making download
- Spin Selling de Neil Rackham
- Spin Selling de Neil Rackham pdf
- Spin Selling epub
- Spin Selling ebook
- Spin Selling de Neil Rackham
- Spin Selling de Neil Rackham livre
- Spin Selling de Neil Rackham Télécharger
- Spin Selling de Neil Rackham gratuit

こんにちは!Ashera望月宣雄です^ ^

今回もブリーチなしで外国人風アッシュカラーを作ったのでご紹介します♪

今回はアンダーの色がもとからハイトーンだったので比較的簡単に外国人風カラーに仕上げることができました!

 

そして2016年春の新色「フレンチセピアアッシュ」を使って外国人風にしあげました☆

この色は程よいグレイ感とツヤ感が楽しめる色になっています☆

こちらです

 

f:id:ashera:20160221152624j:plain

このアンティーク調のなんとも言えないアッシュはこの新色のセピアアッシュならではの色です^_^

 

毛先の方にハイライトを入れて、より透明感と動きを出しましたー^ ^

 

毛先にハイライトを入れることによって若干グラデーションのようなスタイルにもなるのでデザイン的にも飽きがこないスタイルかなと思います☆

 

カットは巻き髪が多いお客様だったので巻きやすいようにレイヤーを入れたスタイルになっています!!

 

春に向けての外国人風イメチェンならお任せください♪

 

ご予約&メニュー料金詳細はこちら☆

↓   ↓   ↓

全メニュー25%off!!メニュー&プライス&アクセス - 全メニュー25%OFF Ashera望月宣雄指名 はてなブログ特別クーポン&アクセス

音譜メリークリスマス音譜

皆様、素敵なクリスマスをお過ごし下さいクリスマスツリー

*********************

前回の続きです。

(前回の記事:コンビ ニンナナンナ )

マコの1歳の誕生日の頃、

コンビのニンナナンナを持ち歩くのに

少し不便を感じた我が家。

だって、ベビーカーのカゴも小さいので

抱っこ紐を入れたらもうパンパンだったのです。

(ベビーカーの記事:コンビ メチャカル )

そんな訳で、今更エルゴではなく

軽量タイプのものを買うことに。

いろいろ考え、キウミの抱っこ紐に決めました!

★送料無料★キウミの抱っこ紐Mドットアプリコットkiumi子守帯抱っこひもだっこひもキウミベビーkiumibaby子守帯・スリング子守帯【あす楽対応】【RCP】

★送料無料★キウミの抱っこ紐Mドットアプリコットkiumi子守帯抱っこひもだっこひもキウミベビーkiumibaby子守帯・スリング子守帯【あす楽対応】【RCP】

★送料無料★キウミの抱っこ紐Mドットアプリコットkiumi子守帯抱っこひもだっこひもキウミベビーkiumibaby子守帯・スリング子守帯【あす楽対応】【RCP】

このキウミの抱っこ紐、意外といいです!

このポーチに入っちゃう大きさなんですから。

どこへでも気軽に持って行けます。

肩への負担が減るよう考えられたデザインですが

やっぱり長時間向けでは無いかな。

ベビーカーと併用したり、

あんよが疲れちゃった時に一時的に

使うものとして、とてもGOODラブラブ

動物園でも活躍しました。

製品の説明では「首すわり~18kgの子まで使える」と

書いてあります。

18kgって凄いな・・・。

2つめの抱っこ紐として、

大活躍してくれました音譜

ソーマが生まれてからは、さらに2本増えるのですが

それはまたの機会に書きます!!

ポイント10倍★★送料無料★ キウミの抱っこ紐 M ドットアプリコット kiumi 子守帯 抱っこひも ...

ポイント10倍★★送料無料★ キウミの抱っこ紐 M ドットアプリコット kiumi 子守帯 抱っこひも ...

価格:4,212円(税込、送料込)

文芸・児童・芸能部門のランキングです。 

f:id:tanazashi:20160214112053j:plain

東京・丸善丸の内本店調べ(10月27日~11月2日)

 

  • 1「夜行」森見登美彦 著(小学館)
  • 2「国家とハイエナ」黒木亮 著(幻冬舎)
  • 3「天子蒙塵 第一巻」浅田次郎 著(講談社)
  • 4「九十歳。何がめでたい」佐藤愛子 著()
  • 5「黒い巨塔 最高裁判所」瀬木比呂志 著(講談社)
  • 6「トヨトミの野望 小説・巨大自動車企業」梶山三郎 著(講談社)
  • 7「〆切本」左右社編集部 編(左右社)
  • 8「恋のゴンドラ」東野圭吾 著(実業之日本社)
  • 9「リーチ先生」
  • 10「慈雨」柚月裕子 著(集英社)

1「夜行」森見登美彦 著(小学館)

僕らは誰も彼女のことを忘れられなかった。

私たち六人は、京都で学生時代を過ごした仲間だった。十年前、鞍馬の火祭りを訪れた私たちの前から、長谷川さんは突然姿を消した。十年ぶりに鞍馬に集まったのは、おそらく皆、もう一度彼女に会いたかったからだ。夜が更けるなか、それぞれが旅先で出会った不思議な体験を語り出す。私たちは全員、岸田道生という画家が描いた「夜行」という絵と出会っていた。旅の夜の怪談に、青春小説、ファンタジーの要素を織り込んだ最高傑作! 「夜はどこにでも通じているの。世界はつねに夜なのよ」 

夜行

夜行

  • 作者: 森見登美彦
  • 出版社/メーカー: 小学館
  • 発売日: 2016/10/25
  • メディア: 単行本
  • この商品を含むブログ (8件) を見る
 

 

2「国家とハイエナ」黒木亮 著(幻冬舎)

破たん国家の国債を二束三文で買い叩き、欧米で勝訴判決をとり、タンカーや外貨準備や人工衛星を差し押さえて、投資額の10倍、20倍のリターンをむしり取る「ハイエナ・ファンド」。狙われた国家は、合法的手段で骨の髄までしゃぶられる―。恐るべき現実を描く、本格派国際金融小説! 

国家とハイエナ

国家とハイエナ

  • 作者: 黒木亮
  • 出版社/メーカー: 幻冬舎
  • 発売日: 2016/10/27
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

3「天子蒙塵 第一巻」浅田次郎 著(講談社)

清朝最後の皇帝・溥儀は、紫禁城を追われながらも、王朝再興を夢見ていた。イギリス亡命を望む正妃と、史上初めて中華皇帝との離婚に挑んだ側妃とともに、溥儀は日本の庇護下におかれ、北京から天津へ。そして、父・張作霖の力を継いだ張学良は失意のままヨーロッパへ。二人の天子は塵をかぶって逃げ惑う。ラストエンペラー・溥儀と二人の女。時代の波に呑み込まれた男女の悲劇と壮大な歴史の転換点を描く。 

天子蒙塵 第一巻

天子蒙塵 第一巻

  • 作者: 浅田次郎
  • 出版社/メーカー: 講談社
  • 発売日: 2016/10/27
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

4「九十歳。何がめでたい」佐藤愛子 著()

収録されたエッセイの中には、15年に大阪・寝屋川市で起きた中学1年の少年少女殺害事件や、16年に発覚した広島・府中市の中学3年生の「万引えん罪」自殺問題から、
高嶋ちさ子さんのゲーム機バキバキ事件や橋下徹元大阪市長のテレビ復帰に至るまで、
折々の出来事と世間の反応について歯に衣着せぬ物言いで迫ったものもあります。とりわけそうした時評からは、怒れる作家と称される佐藤さんのあたたかな眼差しが心に沁み入ります。世間で論じられていた視点とは全く違う、佐藤さんならではの視点にも注目してください。 

九十歳。何がめでたい

九十歳。何がめでたい

  • 作者: 佐藤愛子
  • 出版社/メーカー: 小学館
  • 発売日: 2016/08/01
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

5「黒い巨塔 最高裁判所」瀬木比呂志 著(講談社)

最高裁に君臨する歴代最高の権力者にして「超」エリートの須田謙造最高裁長官。司法権力躍進のために手段を選ばぬ須田は、頻発する原発訴訟で電力会社に有利な判決を出すよう、事務総局を通じて裁判官たちを強引にあやつる。徹底的な信賞必罰による人事統制に恐れをなす司法エリートたちは、誰一人須田にさからえない。ソ連の強制収容所を彷彿とさせる思想統制に違和感を覚える民事局付の笹原駿は、図らずも須田と対峙する道を選ぶ。最高裁中枢を知る元エリート裁判官が描く、あまりにもリアルな、司法荒廃と崩壊の黙示録! 

黒い巨塔 最高裁判所

黒い巨塔 最高裁判所

  • 作者: 瀬木比呂志
  • 出版社/メーカー: 講談社
  • 発売日: 2016/10/28
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る
 

 

6「トヨトミの野望 小説・巨大自動車企業」梶山三郎 著(講談社)

“日本の救世主”は、ハズレ社員だった。創業家vs.左遷サラリーマン!血が勝つか、汗が勝つか―気鋭の経済記者が覆面作家となって挑むメディア禁制・28兆円のタブー!! 

トヨトミの野望 小説・巨大自動車企業

トヨトミの野望 小説・巨大自動車企業

  • 作者: 梶山三郎
  • 出版社/メーカー: 講談社
  • 発売日: 2016/10/19
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

7「〆切本」左右社編集部 編(左右社)

しめきり。そのことばを人が最初に意識するのは、おそらく小学生の夏休みです――。

本書は、明治から現在にいたる書き手たちの〆切にまつわる
エッセイ・手紙・日記・対談などをよりぬき集めた“しめきり症例集"とでも呼べる本です。

〆切本

〆切本

  • 作者: 夏目漱石,江戸川乱歩,星新一,村上春樹,藤子不二雄?,野坂昭如など全90人
  • 出版社/メーカー: 左右社
  • 発売日: 2016/08/30
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (8件) を見る
 

 

8「恋のゴンドラ」東野圭吾 著(実業之日本社)

真冬に集う男女8人の運命は? あの東野圭吾が“恋愛"という永遠のミステリーに真っ向から挑む。衝撃の結末から目を逸らすな!

恋のゴンドラ

恋のゴンドラ

  • 作者: 東野圭吾
  • 出版社/メーカー: 実業之日本社
  • 発売日: 2016/11/01
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る
 

 

9「リーチ先生」

日本の美を愛し続けた英国人陶芸家、バーナード・リーチ。明治42年、22歳で芸術の道を志して来日。柳宗悦、濱田庄司ら若き日本人芸術家との邂逅と友情が彼の人生を大きく突き動かしていく。明治、大正、昭和にわたり東洋と西洋の架け橋となった生涯を描く感動の“アートフィクション”

リーチ先生

リーチ先生

  • 作者: 原田マハ
  • 出版社/メーカー: 集英社
  • 発売日: 2016/10/26
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

10「慈雨」柚月裕子 著(集英社)

警察官を定年退職した神場智則は、妻の香代子とお遍路の旅に出た。42年の警察官人生を振り返る旅の途中で、神場は幼女殺害事件の発生を知り、動揺する。16年前、自らも捜査に加わり、犯人逮捕に至った事件に酷似していたのだ。神場の心に深い傷と悔恨を残した、あの事件に―。元警察官が真実を追う、慟哭のミステリー。 

慈雨

慈雨

  • 作者: 柚月裕子
  • 出版社/メーカー: 集英社
  • 発売日: 2016/10/26
  • メディア: 単行本
  • この商品を含むブログを見る
 

 

目次

  1. WebAssemblyとは
  2. サンプルを動かしてみる
  3. サンプルの動作を解説する
  4. まとめ

 

f:id:shogonir:20170514025514p:plain

1. WebAssemblyとは

WebAssembly(wasm)とは、JavaScript高速化の最新技術です。
JavaScriptの高速化技術であるasm.jsがさらに進化したものです。
C/C++, Rust, Goなどの言語で記述したソースコードを、LLVMなどを用いて.wasm拡張子のバイナリにコンパイルし、JSから呼び出すことが可能になります。

1.1. WebAssembly誕生の経緯

事前にコンパイルを行い、できる処理に制限を加える(DOMやUIの操作が制限され、
値計算がメインになっている)ことで高速化を可能にしたのがasm.jsでした。
しかし、asm.jsのソースコードをブラウザ側でコンパイルするため、ソースコードの容量が大きいとロードタイムが長くなることが問題でした。
それを解決するため、ソースコードをバイナリにして容量を節約しようという発想です。

 

1.2. WebAssemblyの歴史

Wikipediaによると、2017/03/07に初のWebAssembly対応ブラウザFirefox 52.0がリリースされました。
2017/05/14現在では、Google Chrome 57~58, Firefox 52~53, Opera 44, Chrome for Android 57 が対応しています。Safari, Edge は未対応です。
現在のブラウザ対応状況は下記のCan I useで確認できます。
https://caniuse.com/#search=wasm

現状では対応ブラウザも不十分ですし、資料やドキュメントも不足していますが、私はWebAssemblyを勉強する価値があると思います。

 

1.3. WebAssemblyのいいところまとめ

  1. 高速化
  2. 型がある世界でプログラムを書ける
  3. 最終的にバイナリになるので、アルゴリズムやソースコードをユーザから隠せる

 

2. サンプルを動かしてみる

WebAssemblyについていくつか説明しましたが、やはり理解するのに一番いいのは使ってみることでしょう。
というわけで、WebAssemblyのDevelopers Guideに書いてあるGetting Startedを実際にやってみましょう。

※ここからはDockerとnpmがインストールされている前提で話を進めますので、入っていない方は事前に準備してください。

※追記:githubにソースを上げました。

github.com

 

2.1. WebAssembly の Getting Started

Developer’s Guide - WebAssembly

こちらのDevelopers Guideでは環境構築の方法とサンプルコードの動作確認の方法が記述されています。
環境構築としてはemsdk(emscripten sdk)のインストールが推奨されています。
これをまじめにやると2時間ほどかかり容量も15GBほどとられますので、この記事ではDockerを使って環境構築をスキップします。

 

2.2. サンプルコードをコンパイルする

適当な新規ディレクトリに下記のコードをhello.cとして保存します。

#include <stdio.h>
int main(int argc, char ** argv) {
    printf("Hello, world!¥n");
    return 0;
}

Dockerコンテナ上でコンパイルを実行する。

docker run --rm -t -v $(pwd):/src gifnksm/emscripten-incoming emcc hello.c -s WASM=1 -o hello.html
  • docker run でDockerコンテナを立ち上げます
  • --rmオプションでDockerイメージのキャッシュを破棄します
  • -v $(pwd):/srcでカレントディレクトリをDockerコンテナの/srcにマウントします
  • gifnksm/emscripten-incomingはDockerイメージの名前でemsdkがインストールされています。
  • emcc hello.c -s WASM=1 -o hello.htmlはコンパイルのコマンドで、WebAssembly - Developers Guideに書いてあるものと全く同じものです。

 

2.3. サンプルの動作を確認する。

http-server コマンドでサーバを立ち上げ、ブラウザからhttp://localhost:8080/hello.htmlにアクセスして動作確認を行います。
次のような画面になれば成功です。

f:id:shogonir:20170514023351p:plain

動かない場合は下記の注意事項を確認してください。

  • Edge, SafariはWebAssemblyに非対応なので、対応ブラウザで確認してください
  • http-serverコマンドが登録されていない場合はnpm install --global http-serverで導入してください
  • http-serverは8080番ポートが空いてない場合は違うポート番号をとります。Connection refused系のエラーが出た場合はhttp-serverコマンドを実行したターミナルにポート番号が書いてあると思いますので確認してください

 

2.4. 成果物の確認

下記のファイルが生成されていることを確認します。

  • hello.wasm
  • hello.js
  • hello.html

hello.wasm
 hello.cをLLVMなどを用いてwasm形式にコンパイルしたバイナリです。

hello.js
 hello.wasmのコンパイルなどをラップしたjsファイルで、emsdkのemccコマンドが自動生成してくれます。

hello.html
 先ほどブラウザで確認したHTMLです。hello.jsを読み込んで画面に反映させています。

 

3. サンプルの動作を解説する

emccコマンドで生成したjsを使ってwasmを読み込んだ場合、読み込みが完了した際に.cのmain関数が実行されます。
今回実行したemccのオプションではwasm側でprintf()を実行すると、JS側のModule.print()が実行されるようになっているようです。
Module.print()の定義はhello.htmlの最後の方にあります。

<script>
var Module = {
    ...
    print: (function() {
        var element = document.getElementById(output);
        if (element) element.value = ; // clear browser cache
        return function(text) {
            if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join( );
            console.log(text);
            if (element) {
                element.value += text + " ";
                element.scrollTop = element.scrollHeight; // focus on bottom
            }
        };     })(),     ... }; </script> <script async type="text/javascript" src="hello.js"></script>

このようにsample.jsを読み込む前にModuleオブジェクトを定義することで、wasm読み込みに干渉することができます。

 

4. まとめ

この記事ではWebAssemblyとは何かを説明し、最小構成のサンプルを実行するとこまで書きました。

せっかく高速化技術なので、今後はJSとの速度比較サンプルなどを作ってみたいと思います。