0

これよりも argv 関数を処理する効率的な方法はありますか?

ffi.cdef [[ 
  void fooArgv(int argc, const char ** argv, const size_t * argvlen); 
]]

local foo = function(...)
  local nargs = select("#", ...)
  local argv = { }
  local argvlen = { }

  for i = 1, nargs do
    local v = tostring( (select(i, ...)) )
    argv[i] = v
    argvlen[i] = #v
  end

  return ffi.C.fooArgv(
      nargs,
      ffi.new("const char * [" .. nargs .. "]", argv),
      ffi.new("const size_t [" .. nargs .. "]", argvlen)
    )
  end
end
4

1 に答える 1

2

が何度も呼び出される場合fooは、関数の下部を簡単に最適化できます。文字列引数を指定して呼び出すffi.newと、LuaJIT は毎回 C パーサーを実行するように強制されますが、これは最適ではありません。関数は、代わりに使用される特定の型のコンストラクターffi.typeofを作成できます。ffi.new

また、selectループで関数を使用すると、配列を作成してそこからインデックスを作成するよりも遅いと思います。これはよくわかりません。

だからここに私の提案されたバージョンがあります:

ffi.cdef [[ 
  void fooArgv(int argc, const char ** argv, const size_t * argvlen); 
]]

local argv_type = ffi.typeof("const char* [?]")
local argvlen_type = ffi.typeof("const size_t [?]")

local foo = function(...)
  local nargs = select("#", ...)
  local argv = { ... }
  local argvlen = { }

  for i = 1, nargs do
    local v = tostring( argv[i] )
    argv[i] = v
    argvlen[i] = #v
  end

  return ffi.C.fooArgv(
      nargs,
      argv_type(nargs, argv),
      argvlen_type(nargs, argvlen)
    )
end
于 2012-12-23T18:50:12.730 に答える