slimduetを使って海外でインターネット接続を確保する

先日、初めて海外に行ってきた んですが、その際、slimduet というeSIM(ソフトウェア的な設定で通信事業者を変更出来るSIM)を使用してネットワーク通信をしたので、設定方法などをまとめておきます。 前提 端末はFREETELのKiwami 2 (Androidのバージョンは6)、行き先はデンマーク/コペンハーゲンです。 設定 SIMを購入する slimduetを使用するには専用のeSIMが必要ですので、公式サイト やAmazon(記事執筆時点では在庫なし)から購入しておきます。 SIMカードの価格はは2000円を切る程度です。 slimduetのアプリをインストールする slimduetを使用するには、専用のアプリをインストールする必要があります。 Google Playでslimduet と検索し、インストールします。 勿論、この段階では別途データ通信が出来る必要があります。 プランを購入する slimduet SIMを端末に挿入してから、行き先に併せたプランを購入します。 この段階では、Wi-Fiなどのデータ通信が出来る必要がありますので、空港やホテルのWi-Fi等を使用するか、日本国内にいる内に購入しておきます。 slimduetアプリを起動すると、行き先の検索画面が表示されますので、行き先を入力し検索します。 今回はデンマークですので、「デンマーク」と入力し、検索バー横のルーペボタンを押します(キーボードのGoやDone、エンターなどでは検索されないので注意)。 おすすめプラン、ということでデンマークで使えるプランが表示されますので、選択します。 国別プランを選択すると画面が変わり、1日間、3日間などのプランが表示されますので、日程にあわせた期間のプランを選択します。 クレジットカードなどで購入手続きをした後、画面下部の「私の電話番号」を押し、購入したプランが表示されていることを確認します。 また、この段階でSMSで購入したプランについてメッセージが来るはずです。 電話番号を切り替える 自動電話番号切り替えに対応した端末では、プランの「詳細」から、「携帯電話番号の切り替え」を押すことで切り替えることが出来ます。 Kiwami 2は対応していないため、SIM Toolkitを使用して番号の切り替えを行います。 AndroidのアプリドロワーからSIM Toolkitを起動します。 SIM Toolkitを起動すると、SIMの一覧が表示されるので、slimduetかな?と思われるものを選択します。 SIMを選択したら、「携帯電話番号を切り替え」、「ご利用する携帯電話番号を選択してください」の順で選択します。 「携帯電話番号を切り替え」のあと、「設定」を選択したくなりますが、こちらではないため注意します(図の赤枠で示した部分を選択します)。 購入したプランが表示されますので、選択します。 APNの設定をする 電話番号の切り替えが出来たら、APNの設定をします。 Androidの設定から、「SIMカードとモバイル通信」の設定画面を開きます。 「モバイルネットワーク設定」を開き、データ通信を有効にする、データローミング、にそれぞれチェックを入れます。 「アクセスポイント名」の設定画面を開き、右上の + からAPNの設定を追加します。 名前は適当なもの(slimduetなど)を入力し、APNを uinternetとして保存します。 保存したら、作成したAPN設定を選択します。 この時点でデータ通信が出来るようになっているハズです。 この時点でデータ通信が出来ない場合、通信事業者を適切なものに設定する必要がある可能性があります。

2018-05-07 · nasa9084

KubeCon + CloudNativeCon Europe 2018にいってきた

過ぎし5月1日〜5月6日、出張でKubeCon + CloudNativeCon Europe 2018 に行ってきました! KubeConはKubernetes(k8s) のイベントで、Cloud Native Computing Foundation(CNCF) が主催するCloudNativeConと併せた開催でした。 今回の開催地はデンマークはコペンハーゲンのBella Centerで、実に4000人以上が参加したとのことです。 twitterハッシュタグは#kubecon で、一部#cloudnativecon も使われていたようです。 私個人としては初海外で、初日の移動で腰をぎっくりするなど、トラブルに見舞われながらも、なんとかこんとか行ってきました。 finnair 今回、飛行機はFinnair を使用しました。 成田空港からヘルシンキ、ヘルシンキからコペンハーゲンの一回乗り継ぎです。 成田空港からヘルシンキは約10時間、ヘルシンキからコペンハーゲンは約1.5時間のフライトです。 成田空港からヘルシンキのフライトでは、機内に備え付けのヘッドホンがノイズキャンセラー付きで、意外と音もよく、また、機内食もそこそこおいしかったため、比較的お勧め出来る航空会社かと思います。 成田空港からヘルシンキのフライトはJALも含めたコードシェア便だったため、機内の放送では日本語でも放送される点が安心感があって良いなと感じました。 The Square 今回とったホテルはコペンハーゲンの繁華街にほど近いThe Square というホテルです。 繁華街に近いため、観光にも困らず、飲み会をした後にも戻りやすい立地でした。 近所にはNETTO という24時間営業の比較的安いスーパーや、お土産の購入等にも便利なIrma という高級スーパーもあり、買い物には困ることがありませんでした。 繁華街まで脚を伸ばせば、Hard Rock Cafe や、国内でも一時期話題となったSuperdry1などもあります。 また、今回のKubeConのパーティーがTivoli garden での開催だったため、パーティー会場がホテルの隣のブロック、という点でも非常に良い立地でした。 ホテルそのものも、おしゃれで、清潔な感じのホテルでした。 シャワーが出ないということもありませんでしたし、最低限のアメニティも揃っていました。 冷蔵庫が壊れていたのか、中の飲み物等を冷やしてくれないのだけが少々残念でした。 KubeCon + CloudNativeCon Europe 2018 KubeCon + CloudNativeCon Europe 2018は非常に多くのトラックがあり、その多くのスライドがPDFで公開されています。 スライドはスケジュール からダウンロードすることができます。 また、@superbrothers さんが一気にダウンロードするスクリプトを書いてくださっているので、こちらを使用することも出来ます。 I created a script that downloads all KubeCon + CloudNativeCon Europe 2018 slides from Sched! ? https://t.co/FyD1zhJbNk #KubeCon ...

2018-05-07 · nasa9084

Kubernetesのセキュリティのベストプラクティス by Ian Lewis

Japan Container Days v18.04 で表題のセッションを聞いたので、まとめました。 スライド資料 Kubernetesのセキュリティのベストプラクティス(SpeakerDeck) APIサーバへの攻撃を防ぐ RBACでPodに付与される権限を絞る Podにはシークレットが自動でマウントされるため、不正アクセスにより読み込まれてしまうと危ない FirewallでAPIサーバへのアクセスについてIP制限を付与する いざ、シークレットが漏れた場合でも、APIサーバにアクセスされてしまわないように、ファイアウォールでIP制限をかけておくと良い NetworkPolicyでDBへの接続が許可されるPodを制限する 大体の場合、重要なデータはDBに有るため、DBへのアクセスを絞ることで安全性を上げる example: 1 2 3 4 5 6 7 8 9 10 11 12 13 kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: redis spec: podSelector: matchLabels: name: redis ingress: - from: - podSelector: matchLabels: name: guestBook ホストへの攻撃を防ぐ 次の三つを併用すると良い non-rootユーザでPodを実行する example: 1 2 3 4 5 6 7 kind: Pod apiVersion: v1 metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 読み込み専用ファイルシステムを使用する example: 1 2 3 4 5 6 7 kind: Pod apiVersion: v1 metadata: name: security-context-demo spec: securityContext: readOnlyRootFilesystem: true no_new_privs forkしたプロセスが強い権限を持てないようにする ...

2018-04-19 · nasa9084

Raspberry PiのヘッドレスインストールでWi-Fiを設定する

uzullaさんがブログでこんなことを書いてた。 しかし…/boot/のどこかに起動後実行されるスクリプトがあれば楽なのにな…(そこで無理やりwifi情報を書き込めば良いわけで) ヘッドレスRaspberry Pi Zero w(h)のコンソールやネットワークなど初期設定についてメモ - uzullaがブログ 私も過去何度かRaspberry Pi Zeroのヘッドレスインストールをしてまして、実はヘッドレスインストールの時にWi-Fi情報を書き込めるファイルがあるのです。 /boot/wpa_supplicant.confというファイルで、ここにWi-Fiの設定を書き込んで起動すると、raspbianが/etc/wpa_supplicant/wpa_supplicant.confに良い感じにコピーしてくれます。 上記uzullaさんのブログでいうと、「microSDのファイルを編集」の時に一緒に書き込んでおくと、起動時にその情報を使ってWi-Fiをつかんでくれます。 あとはnmapするなり、ルータやらDHCPサーバやらのリース状況を確認するなりでラズパイに割当たったIPをゲットしてssh pi@xxx.xxx.xxx.xxx的にSSHするか、avahi/bonjourをつかってssh pi@raspberrypi.local的にSSHするかでログインできます。 wpa_supplicant.confの書き方は、上記uzullaさんのブログ記事の、「Raspberry Pi Zero wにWifiを設定する」ってところを見るか、ここ とかここ にジェネレータを作ってくれてる人がいるので、利用して生成すると良いと思います。 パスワードは平文でOKなので、適当な文字列を突っ込んで手元で書き換えると安心かもしれないです。 なお、NOOBSでやるときは、wpa_supplicant.confとsshは/bootではなく、ルートディレクトリにおけばOKです。 さらに、recovery.cmdlineと言うファイルのquietという部分をvncinstallに書き換えることで起動したNOOBSにVNC接続できるようになります。

2018-04-18 · nasa9084

TOTPを実装する

ここ数年で多くのサービスで採用されてきている二要素認証ですが、皆さん使っているでしょうか。 私は実は最近までは面倒であまり使っていなかったのですが、ようやく重い腰を上げてあちこち設定しました。 そのうち、近年特によく使われているのがTOTP(Time-Based One-Time Password)と呼ばれるアルゴリズムです。 TOTPアルゴリズムはRFC6238 で定義されたアルゴリズムで、サーバとクライアントが共有する秘密鍵および現在時刻から確認用のコードを生成するものです。 RFCやWikipedia を見てわかるよう、かなり簡素なアルゴリズムで、一つ一つ理解していけば比較的簡単に実装することができます。 Go言語のコードを実例に、サンプルコードを実装してみます。 HOTPとTOTP TOTPアルゴリズムとよく似たものに、HOTP(HMAC-Based One-Time Password)と呼ばれるアルゴリズムがあります。 これは、サーバとクライアントが共有する秘密鍵と、「何回目の認証か」から確認用のコードを生成するアルゴリズムです。 HOTPアルゴリズムは(勿論)アルゴリズムですから、ある計算手順であり、秘密鍵と認証回数を引数にとって認証用コードを返す関数として表すことができます。 この、認証回数という引数に対して、現在時刻を入力したものがTOTPです。 認証「回数」というくらいですから、値は正の整数値です。時刻を整数として入力するため、UnixTimeを使用します。 実際にはUnixTimeそのままで入力すると1秒ごとに認証用コードが変わってしまい実用できではありませんから、ある秒数を一周期として、現在が何周期目なのか、という値を入力します。 TOTPを実装する 扨、前置きはこれくらいにしてTOTPアルゴリズムを実装します。 次の式で表されます。 \begin{eqnarray*} TOTP(K, T_0, X) &=& HOTP(K, T(T_0, X)) \\ T(T_0, X) &=& \frac{(CurrentUnixTime - T_0)}{X} \end{eqnarray*} $K$は共有秘密鍵です。 $T_0$は数えはじめの時間で、通常はUnix epoch、すなわち0を使用します。 $X$は一周期の秒数で、規定値は30秒です。(実際、多くのサービスが30秒ベースです) プログラム実装は以下の様に書いてみます。 1 2 3 4 5 6 7 func TOTP(k string, t0, x int) int { return HOTP(k, T(t0, x)) } func T(t0, x int) int { return (time.Now().Unix - t0)/x } 簡単ですね。上記の内、定義されていないのはHOTP(K, T)だけとなりました。 HOTPを実装する TOTPのコードではHOTPアルゴリズム部分が実装されていませんので、ここを実装すれば実際に使用できるはずです。 HOTPアルゴリズムはRFC4226 で定義されているので、これを読みながら実装します。 RFCを読むと、HOTPは大きく次の3ステップで求められることがわかります。 共有秘密鍵と認証回数からHMAC-SHA1の値を求める 4byteの文字列を生成する HOTPの値を計算する 何が何やらですね。もう少し詳しく見ていきましょう。 1. HMAC-SHA1の値を求める HMACはメッセージ認証コードの一種で、ハッシュ関数を使用し、秘密鍵とメッセージから認証コードを生成します。 ここでは、その名の通り、ハッシュ関数としてSHA1を使用します。 また、メッセージとして認証回数を使用します。 ...

2018-03-30 · nasa9084

Golang: 配列からスライスに変換する

TL;DR: slice := array[:]で変換できる Go言語にはリストの様なものが二つあります。配列(固定長)とスライス(可変長)です。 一般に、Go言語で配列を扱うことは多くないでしょう。 実際、多くのパッケージ(標準パッケージを含む)が要求するのはスライスです。 とは言っても一部のパッケージでは配列を取り扱っているものがあります。 例えば、crypto/sha512を見てみる と、以下の様な関数が存在します。 1 func Sum512(data []byte) [Size]byte ここで、Sizeは同パッケージ内で宣言されている定数で、値は64です。 つまり、この関数は64バイトの長さを持った配列を返します。 この関数は与えられたデータからSHA512チェックサムを計算するものです。 勿論、返ってきた値をそのまま使用することもあるとは思いますが、そのままの値は人間可読な値では無いため、hexdigestを得たいと思うでしょう。 Go言語にはもちろんのことながら、encoding/hexパッケージが存在し、簡単に16進文字列を得ることができます。 16進表記の文字列を得るためには、次の関数を使用します。 1 func EncodeToString(src []byte) string 引数に注目します。 要求されているのはbyteのスライスです。 Goでは、配列とスライスは基本的に別物ですから、以下の様に書くことはできません。 1 2 3 4 h := sha512.Sum512("foobar") // 型エラーが発生する EncodeToString(h) そうは言っても、配列とスライスは非常に似ています。 次のように書きたくなりますね。 1 2 h := sha512.Sum512("foobar") EncodeToString([]byte(h)) // 配列をスライスに変換したい しかし、次のようなエラーを生じます。 cannot convert sha512.Sum512("foobar") (type [64]byte) to type []byte 型変換はできないようです。 どうしたら良いのでしょうか。 Go言語では、配列の範囲インデックスを使った場合、返される値はスライスとなります。 1 2 a := [3]string{"foo", "bar", "baz"} s := a[0:2] // sはスライス また、インデックスを省略することもできます。 開始値を省略すれば、0を与えたものと見なされますし、終了値を省略すれば、配列の最後までを切り取ります。 1 2 3 a := [3]string{"foo", "bar", "baz"} s1 := a[:2] // a[0:2]と等しい s2 := a[0:] // a[0:3]と等しい では、両方省略するとどうなるでしょうか。 両方省略すると、もとの配列と同じ内容のスライスが返されます。 ...

2018-03-16 · nasa9084

Let's Encryptでワイルドカード証明書を取得する

先日twitterでサポートされたと発表されたLet’s Encryptのワイルドカード証明書ですが、本日未明、正式にcertbotがワイルドカード証明書に対応したと発表されました !1 早速ですが、実際にワイルドカード証明書を取得してみます。 尚、今回対象とした環境は以下のとおりです。 CentOS 7 リバースプロキシとしてnginx DNSはGehirn DNS では、作業していきます。 CentOS 7でcertbotを使用する場合、大抵はyumでcertbotをインストールしていると思いますので、まずはアップデートします。 1 $ sudo yum update 出力は省略しますが、certbotが0.22.0にアップデートされます。 0.22.0はワイルドカード対応バージョンですので、問題ないですね! 公式のマニュアルでは、dns-pluginを使うよう書いてあり ますが、Gehirn DNSのプラグインは無いため、今回は手動で行きます。 以下のコマンドを実行します。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 # certbot certonly --manual --preferred-challenges dns -d *.web-apps.tech --server https://acme-v02.api.letsencrypt.org/directory Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): nasa.9084.bassclarinet@gmail.com Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org ------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory ------------------------------------------------------------------------------- (A)gree/(C)ancel: a ------------------------------------------------------------------------------- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. ------------------------------------------------------------------------------- (Y)es/(N)o: y Starting new HTTPS connection (1): supporters.eff.org Obtaining a new certificate Performing the following challenges: dns-01 challenge for web-apps.tech ------------------------------------------------------------------------------- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? ------------------------------------------------------------------------------- (Y)es/(N)o: y ------------------------------------------------------------------------------- Please deploy a DNS TXT record under the name _acme-challenge.web-apps.tech with the following value: qiGA8Vep17l0nYJ1O1AdF68D9iT7bL5Mpoe3j7-Caag Before continuing, verify the record is deployed. ------------------------------------------------------------------------------- Press Enter to Continue 上記のようにTXTレコードを追加するようにメッセージが出たら、指定された値をDNSに追加します。 Gehirnでは以下のような形になります。 ...

2018-03-13 · nasa9084

sygを使用したgraceful shutdown serverパターン

github.com/nasa9084/syg を使用すると、手軽にシグナルとコールバック関数のマッピングを行うことができます1 これを使用し、SIGINTを受けてgraceful shutdownできるHTTPサーバを実装してみます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package app import ( "context" "net/http" "os" "time" "github.com/nasa9084/syg" ) type Server struct { server *http.Server closed chan struct{} } func NewServer() *Server { http.HandleFunc("/", longlongHandler) return &Server{ server: &http.Server{ Addr: ":8080", }, closed: make(chan struct{}), } } func (s *Server) Run() error { // os.Interrupt = syscall.SIGINT cancel := syg.Listen(s.shutdown, os.Interrupt) defer cancel() err := s.server.ListenAndServe() <-s.closed return err } func (s *Server) shutdown(os.Signal) { s.Shutdown(context.Background()) close(s.closed) } func longlongHandler(w http.ResponseWriter, r *http.Request) { // なんか長い処理のつもり time.Sleep(10 * time.Second) w.Write([]byte("hello")) } mainからは以下の様に呼びます。 ...

2018-03-10 · nasa9084

Golang: 手軽にシグナルをListenしてcallback関数を呼ぶ

Go言語でシグナルを取り扱いたい場合、osパッケージおよびos/signalパッケージ、syscallパッケージを使用します。 具体的には、以下のようにします。 1 2 3 4 5 6 7 8 9 10 11 12 13 func main() { sigCh := make(chan os.Signal, 1) doneCh := make(chan struct{}) signal.Notify(sigCh, syscall.SIGINT) go func() { sig := <-sigCh fmt.Println(sig) // (1) close(doneCh) }() <-done } 実際には、(1)の様に受け取ったシグナルを出力するだけではなく、何らかの処理を行うことになるでしょうし、goroutineのリークを避けるためにシグナルの待受をキャンセルする必要が有りますから、contextを使用してfor-selectループを書くことにもなるでしょう。 例として、HTTPサーバをシャットダウンするような処理を考えます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 func main() { sigCh := make(chan os.Signal, 1) doneCh := make(chan struct{}) ctx, cancel := context.WithCancel(context.Background()) signal.Notify(sigCh, syscall.SIGINT) s := &http.Server{ Addr: ":8080", Handler: http.DefaultServeMux, } go func() { for { select { case sig := <-sigCh: sig := <-sigCh s.Shutdown(context.Background()) close(doneCh) case <-ctx.Done(): return } } }() if err := s.ListenAndServe(); err != http.ErrServerClosed { log.Println(err) cancel() return } <-doneCh } シグナルを受け取って、関数の呼び出し(ここではs.Shutdown())をしたいだけなのに、チャンネルを作って、goroutineを立ち上げて、となんとも大仰です。 goroutineで呼び出す関数の中でfor-selectループを使っているため、行数も長くなってしまっています。 ...

2018-03-06 · nasa9084

strings.Builderとbytes.BufferのWrite系関数のベンチマーク

TL; DR 平均して見るとstrings.Builder#WriteXXXの方が速そう strings.Builder Go 1.10からstrings.Builder構造体が追加されました。 公式ドキュメントには、 A Builder is used to efficiently build a string using Write methods. It minimizes memory copying. The zero value is ready to use. Do not copy a non-zero Builder. と説明が書かれています。 おそらく、これまで文字列の組み立てをする際にはbytes.Bufferを使っている場合が多かったと思われますが、そういった目的の選択肢として作られたようです。 が、説明を読んでもいまいち違いがわかりません。 とりあえず、bytes.Bufferとstrings.Builderでは速度面で違いがあるのか調べるべく、ベンチマークを実施しました。 条件 実行した環境 MacBook Air MacOS Sierra 10.12.6 CPU: Core i7 1.7GHz メモリ: 8GB 実行する関数 Write WriteByte WriteRune WriteString exec 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 $ for i in {1..10}; do go test -bench . | tail -n +4 | head -n 8 && echo; done BenchmarkBuilderWrite-4 10000000 129 ns/op BenchmarkBuiderWriteByte-4 200000000 6.47 ns/op BenchmarkBuilderWriteRune-4 200000000 7.61 ns/op BenchmarkBuilderWriteString-4 30000000 92.4 ns/op BenchmarkBufferWrite-4 50000000 196 ns/op BenchmarkBufferWriteByte-4 300000000 9.40 ns/op BenchmarkBufferWriteRune-4 200000000 8.18 ns/op BenchmarkBufferWriteString-4 50000000 217 ns/op BenchmarkBuilderWrite-4 10000000 189 ns/op BenchmarkBuiderWriteByte-4 100000000 10.5 ns/op BenchmarkBuilderWriteRune-4 100000000 10.4 ns/op BenchmarkBuilderWriteString-4 30000000 157 ns/op BenchmarkBufferWrite-4 50000000 238 ns/op BenchmarkBufferWriteByte-4 100000000 19.9 ns/op BenchmarkBufferWriteRune-4 100000000 15.5 ns/op BenchmarkBufferWriteString-4 30000000 422 ns/op BenchmarkBuilderWrite-4 10000000 131 ns/op BenchmarkBuiderWriteByte-4 200000000 7.58 ns/op BenchmarkBuilderWriteRune-4 200000000 8.48 ns/op BenchmarkBuilderWriteString-4 30000000 113 ns/op BenchmarkBufferWrite-4 50000000 199 ns/op BenchmarkBufferWriteByte-4 100000000 10.4 ns/op BenchmarkBufferWriteRune-4 200000000 12.0 ns/op BenchmarkBufferWriteString-4 50000000 382 ns/op BenchmarkBuilderWrite-4 10000000 122 ns/op BenchmarkBuiderWriteByte-4 200000000 7.45 ns/op BenchmarkBuilderWriteRune-4 200000000 8.44 ns/op BenchmarkBuilderWriteString-4 30000000 155 ns/op BenchmarkBufferWrite-4 50000000 264 ns/op BenchmarkBufferWriteByte-4 200000000 7.08 ns/op BenchmarkBufferWriteRune-4 200000000 10.1 ns/op BenchmarkBufferWriteString-4 30000000 413 ns/op BenchmarkBuilderWrite-4 20000000 117 ns/op BenchmarkBuiderWriteByte-4 200000000 6.81 ns/op BenchmarkBuilderWriteRune-4 200000000 6.87 ns/op BenchmarkBuilderWriteString-4 50000000 219 ns/op BenchmarkBufferWrite-4 20000000 101 ns/op BenchmarkBufferWriteByte-4 200000000 6.22 ns/op BenchmarkBufferWriteRune-4 200000000 12.2 ns/op BenchmarkBufferWriteString-4 50000000 513 ns/op BenchmarkBuilderWrite-4 10000000 161 ns/op BenchmarkBuiderWriteByte-4 200000000 8.36 ns/op BenchmarkBuilderWriteRune-4 200000000 8.24 ns/op BenchmarkBuilderWriteString-4 30000000 109 ns/op BenchmarkBufferWrite-4 50000000 296 ns/op BenchmarkBufferWriteByte-4 100000000 10.6 ns/op BenchmarkBufferWriteRune-4 100000000 11.4 ns/op BenchmarkBufferWriteString-4 50000000 484 ns/op BenchmarkBuilderWrite-4 10000000 133 ns/op BenchmarkBuiderWriteByte-4 200000000 7.16 ns/op BenchmarkBuilderWriteRune-4 200000000 8.10 ns/op BenchmarkBuilderWriteString-4 30000000 194 ns/op BenchmarkBufferWrite-4 50000000 190 ns/op BenchmarkBufferWriteByte-4 200000000 5.51 ns/op BenchmarkBufferWriteRune-4 200000000 8.72 ns/op BenchmarkBufferWriteString-4 50000000 281 ns/op BenchmarkBuilderWrite-4 10000000 136 ns/op BenchmarkBuiderWriteByte-4 200000000 11.4 ns/op BenchmarkBuilderWriteRune-4 50000000 28.0 ns/op BenchmarkBuilderWriteString-4 10000000 119 ns/op BenchmarkBufferWrite-4 20000000 144 ns/op BenchmarkBufferWriteByte-4 100000000 16.0 ns/op BenchmarkBufferWriteRune-4 200000000 8.43 ns/op BenchmarkBufferWriteString-4 50000000 248 ns/op BenchmarkBuilderWrite-4 10000000 130 ns/op BenchmarkBuiderWriteByte-4 200000000 7.83 ns/op BenchmarkBuilderWriteRune-4 200000000 7.13 ns/op BenchmarkBuilderWriteString-4 30000000 99.0 ns/op BenchmarkBufferWrite-4 50000000 202 ns/op BenchmarkBufferWriteByte-4 200000000 10.7 ns/op BenchmarkBufferWriteRune-4 100000000 13.8 ns/op BenchmarkBufferWriteString-4 50000000 452 ns/op BenchmarkBuilderWrite-4 10000000 146 ns/op BenchmarkBuiderWriteByte-4 200000000 7.89 ns/op BenchmarkBuilderWriteRune-4 200000000 8.24 ns/op BenchmarkBuilderWriteString-4 30000000 122 ns/op BenchmarkBufferWrite-4 50000000 248 ns/op BenchmarkBufferWriteByte-4 100000000 31.7 ns/op BenchmarkBufferWriteRune-4 100000000 25.4 ns/op BenchmarkBufferWriteString-4 30000000 413 ns/op Source ベンチマークスクリプトのソースは以下の様になっています。 ...

2018-03-05 · nasa9084