Fork me on GitHub

2008/07/11


このエントリーをはてなブックマークに追加
卑怯と言われようが構いません。

let X = "ひだまり"
let _ = "スケッチ"

try
  X / _ / X < また見て下さいね
catch /^Vim\%((\a\+)\)\=:E488/
  echo eval(
    \  substitute(
    \    substitute(
    \      v:exception,
    \      '^.*E\(\d\+\).*:\s*\(\(.\) / \(.\).*\). <\(.*\)$',
    \      '\2"\3".(\1-123)."\5"', ''), '/', '.', 'g'))
endtry
Posted at 20:30 in ソフトウェア::vim
Tagged as: tips, vim
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip

2008/06/26


このエントリーをはてなブックマークに追加
vimで自前でYAML読み込むとか面倒くさすぎる。
こう言う時はif_pythonとかif_perlとかを使わせてもらう。運良くvimスクリプトはjsonと相性が良いのでYAMLを読み込み、JSONに変換してvimに戻してあげる。
function! LoadYAML(file)
  perl << EOF
use YAML::Syck;
use JSON::Syck qw(Dump);
eval {
  VIM::DoCommand("let ret = " . Dump(LoadFile("".VIM::Eval('a:file'))));
};
VIM::DoCommand("let v:errmsg = substitute('$@', \"\\n\", '', 'g')") if $@;
EOF
  if !exists('ret')
    throw v:errmsg
  endif
  return ret
endfunction

echo LoadYAML("config.yaml")
戻り値はDictionary形式になります。
読み込めなかった場合はthrowしているのでvim7限定になりますがcatchしてやって下さい。

さて、if_perlですがperl510で動かなくなってました。今日パッチを作成してvim-devに送ったのですが、如何せん自信がありません(Shibuya.xsでvimmerな皆様、どうか私にお力をお貸し下さい)。
パッチは
vim72-perl510-fix.diff
にあります。不具合報告等あればご連絡下さい。
Posted at 19:18 in ソフトウェア::vim
Tagged as: perl, tips, vim, yaml
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip

2008/05/26


このエントリーをはてなブックマークに追加
Tagtterをリリースして、初期は「CPU Quota」連発してしまい見苦しい状態でした。ごめんなさい。
さて、一時はどうなるかと思いましたが現在は「CPU Quota」も表示される事無く動いています。
今日はこの状況を乗り切る際に行った「Google App Engine」のパフォーマンスチューニングtipsを3つほどご紹介。

webapp.WSGIApplicationのdebugフラグはFalseにすべし

いきなり当たり前で申し訳ないですが、実はこのフラグがTrueかFalseかというだけで「CPU Quota」が出る頻度が極度に異なります。
実際に同じ症状の方もいらっしゃる様なので、おそらく間違いありません。
また公開する様なシステムでは、パスワード等も管理される事になるかと思いますが、debug=Trueだとスタックトレースに変数の値が表示されてしまい無茶苦茶危険です。気を付けましょう。
なお、Tagtterではユーザのパスワードは一切保存していません。

時間の掛かる既知な処理はキャッシュする

これはGoogle App Engineだけに言える話ではないですが、Tagtterではユーザの存在確認の為にtwitter.comへアクセスしています。
但し、タグが追加される度、voteされる度にこれを行ってしまうとtwitter.comにも負荷を掛ける事になります。
そこでTagtterではTagtter内に存在するユーザに対してはtwitter.comへのアクセスを行わないようになっています。
確かにGoogle App Engineの処理能力は良いのですが、いかんせん制限が厳しかったりします。余談になりますが現状Tagtterのデータ全件をXMLエクスポートする処理は「CPU Quota」で動きません。現在はデータの種別毎にバックアップしています。

Templateにはクラスオブジェクトは渡さない

Django Templateには、db.Modelのインスタンスを渡せて非常に便利なのですが、このDBインスタンスをTemplateの中から扱うと非常に遅くなります。
またdb.Modelに持ったgeneratorをTemplateから使うと更にパフォーマンスが落ちます。
例えばTagtterではユーザに対して付けられたタグをManyToManyで管理しており、モデルの一部を抜粋すると
class TagtterTag(db.Model):
  name = db.StringProperty(required=True)

  ... snip ...

class TagtterMembership(db.Model):
  user = db.ReferenceProperty(TagtterUser)
  tag = db.ReferenceProperty(TagtterTag)

  ... ship ...

class TagtterUser(db.Model):
  name = db.StringProperty(required=True)

  ... snip ...

  def tags(self):
    return (x.tag for x in self.tagttermembership_set)

この様なコードになるのですが、user.tagsをTemplate側から呼び出すとかなりパフォーマンスダウンになります。また、Google App EngineではCPU占有度により「CPU Quota」させる仕組みがあるのですが、実はこれはTemplate内の呼び出しにも適応される為
application → template → model procedure
という処理を行うと、1処理(1値参照)あたりのCPU使用回数が増える事になります。
つまり上記Tagtterのtagsページでは全てのタグが表示されますがこれを
    template_values = {
      'tags' : TagtterTag.all(),
    }
この様にしてしまうとTemplate側からModelのメソッドを呼び出す事になり、現状のデータ件数だと100%エラーが発生してしまいます。
Google App EngineではCPU占有状態が5秒程続くとエラーになる様で、このブリッジ状態だけでもパフォーマンスダウンに繋がるって事になります。
これを回避する為には、applicationにてTemplateで使う値を全て保持してしまう事が最も効果的でした。
つまり全てdictとして渡してあげるのです。変にTemplate側で「タグの数が0でない物を表示」とするのではなく
    all_tags = []
    for tag in TagtterTag.all():
      if tag.size():
        size = tag.size()
        all_tags.append({
          'name' : tag.name,
          'title' : tag.title,
          'size' : size,
          'fontsize' : font_size(size),
        })
    ... ship ...

    template_values = {
      ... ship ...

      'tags' : all_tags,

      ... ship ...
    }
この様にTemplate側からdb.Modelメソッドを呼び出させないようにするのです。 これで、現状エラーも出なくなりました。要するに極力db.Modelインスタンスにアクセスしない様にするってのが味噌ですね。
こんな品祖貧祖なパフォーマンスチューニングですが、皆さんの何かしらのお役に立てば幸いです。

他にもパフォーマンスチューニングの方法は幾らでもあるかと思います。Tagtterで言えばクライアント側の処理は殆どパフォーマンスチューニングされていないのが現状です。
不定期ですが時間を見付けてやって行きたいと思います。

何かご要望などあれば、Feature Requestまで。
Posted at 18:37 in ソフトウェア::lang::python
Tagged as: google app engine, tips
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip

2008/05/02


このエントリーをはてなブックマークに追加
以前、「Big Sky :: 意外と知られていないvimのtips(vimでソースコードをHTML化するコツ)」という記事を書いて、なかなか好評だったのですが(前のサーバで公開した記事なので反響は見えませんが)、vimでHTMLを編集しておられる方って結構多いと感じました。
私もしかり、このブログにおいても全てvimで編集しています。
ソースコードは上記リンクに記した通り「:TOhtml」を使い、その他はほぼ全て打ち込んでいます。ただ別のサイトにある記事やリンクを引用する場合、少し手間が発生します。例えば
<a href="http://example.com">サンプル</a>
とタイプする場合、ブラウザのアドレスバーからURLを、さらにブックマーク画面を出してタイトルをコピーして上の様な記述に置き換えるとなるとキーボードだけで操作出来なかったりして少し煩わしい感じがしますね。オーサリングツールやmarkdown等で楽する事も出来ますがちょっとした更新で、しかもvimが使いたいなんて場合もありますよね。
また、ブラウザは起動していないけどURLならもう知ってるなんて場合、タイトル抜き出すのが大変なんて思っていませんか?
今日は私が使っているvimスクリプトを紹介してみます。
まずソース
let g:Anchorize_Format = '<a href="%s" class="external" target="_blank">%s</a>'
function! Anchorize_TITLE(url)
  silent! split _FETCHTITLE_
  silent! exec "0r!curl -s ".a:url
  if executable('nkf')
    if &enc == 'utf-8'
      silent! %!nkf -X8
    elseif &enc == 'cp932'
      silent! %!nkf -Xs
    endif
  endif
  silent! %join!
  silent! %g/^\s*$/d _
  silent! %s/^.\{-}<title[^>]*>\([^<]\+\)<\/title>.*/\1/i
  let ret = getline('.')
  silent! bw!
  if exists('Anchorize_Format')
    let format = Anchorize_Format
  else
    let format = '<a href="%s">%s</a>'
  endif
  return printf(format, a:url, ret)
endfunction
function! Anchorize_URL(v)
  let url = input('URL:')
  if len(url)
    if exists('Anchorize_Format')
      let format = Anchorize_Format
    else
      let format = '<a href="%s">%s</a>'
    endif
    if a:v
      silent! normal! gvs
      let word = getreg('"')
      exec "normal! a".printf(format, url, word)
    else
      let word = expand('<cword>')
      exec "normal! ciw".printf(format, url, word)
    endif
  endif
endfunction
nnoremap <leader>,u :call Anchorize_URL(0)<cr>
vnoremap <leader>,u :<c-w>call Anchorize_URL(1)<cr>
vnoremap <leader>,U s<c-r>=Anchorize_TITLE(getreg('"'))<cr><esc>
これをanchorize.vimとかでpluginディレクトリに放り込むとインストール完了。
使い方は、まず
今日もGoogleで検索
の「Google」という部分を「http://www.google.co.jp/」へのリンクにしたい場合には「Google」の部分までカーソルを移動して
<leader>,u
「<leader>」は何も設定していなければ「¥」になっているかと思います。
とタイプすると
URL:
というプロンプトが出るのでここに
URL:http://www.google.co.jp/
とタイプしてENTERを押すと
今日も<a href="http://www.google.co.jp/">Google</a>で検索
と変換されます。また空白を含んだ、例えば「Google Search」の様な場合「Google Search」をビジュアル選択して「<leader>,u」とすれば同じ動作になります。
さらに例えば
今日もhttp://b.hatena.ne.jp/でホットエントリ
というテキストのURL部分をビジュアル選択し、今度は
<leader>,U
「U」は大文字
とタイプすると
今日も<a href="http://b.hatena.ne.jp/">はてなブックマーク - ソーシャルブックマーク</a>でホットエントリ
と変換してくれます。
急いでネタ記事をアップしたいvimmerには重宝するのではないかと思います。なお、動作にはnkfというフィルタコマンドが必要です。Windowsであれば「nkf win32」あたりで検索すればヒットするかと思います。ちなみに、vimrc等でAnchorize_Formatという変数を
let g:Anchorize_Format = '<a href="%s" class="external" target="_blank">%s</a>'
等といった感じに編集する事も出来るので、class属性を常に付けたい人にも使えるかと思います。
元々公開するつもりも無かったスクリプトなので、拡張性ありませんがよろしければどうぞ。
Posted at 18:02 in ソフトウェア::vim
Tagged as: tips, vim
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip