luastring.concatと..パフォーマンスの比較



Lua String Concat



print('-------------------------------------test1-------------------------------------') --[[ Test case: Test simple character stitching --]] local a = 'hello' local b = 'lua' local c = 'world' local startTime = os.clock() local str = nil for i=1, 100000 do str = a .. ',' .. b .. ',' .. c .. ',' .. os.clock() end local endTime = os.clock() print('case1 time used:', endTime - startTime) local startTime = os.clock() local str = nil for i=1, 100000 do - There is performance overhead for creating tables local tb = {} table.insert(tb, a) table.insert(tb, b) table.insert(tb, c) table.insert(tb, os.clock()) str = table.concat(tb,',') end local endTime = os.clock() print('case2 time used:', endTime - startTime) print('-------------------------------------test2-------------------------------------') --[[ Test case: Test long strings --]] local a = 'hellohellohellohellohellohellohellohellohello1' local b = 'hellohellohellohellohellohellohellohellohello2' local c = 'hellohellohellohellohellohellohellohellohello3' local str = nil local startTime = os.clock() for i=1, 100000 do str = a .. ',' .. b .. ',' .. c .. ',' .. os.clock() end local endTime = os.clock() print('case1 time used:', endTime - startTime) local startTime = os.clock() local str = nil for i=1, 100000 do local tb = {} table.insert(tb, a) table.insert(tb, b) table.insert(tb, c) table.insert(tb, os.clock()) local str = table.concat(tb,',') end local endTime = os.clock() print('case2 time used:', endTime - startTime) print('-------------------------------------test3-------------------------------------') --[[ Test case: Test nested strings --]] function getTable2RecordString1(tbRecords) local str = '' for _,value in ipairs(tbRecords) do str = str .. value.dId .. ',' .. value.strName .. ',' .. value.dTest1 .. ',' .. value.dTest2 .. ',' .. value.dTest3 .. ',' .. value.dTest4 .. '' end return str end function getTable2RecordString2(tbRecords) local str = '' local tbResult = {} for _,value in ipairs(tbRecords) do local tbItem = {} table.insert(tbItem, value.dId) table.insert(tbItem, value.strName) table.insert(tbItem, value.dTest1) table.insert(tbItem, value.dTest2) table.insert(tbItem, value.dTest3) table.insert(tbItem, value.dTest4) table.insert(tbResult, table.concat(tbItem, ',')) end str = table.concat(tbResult, ',') return str end local tbRecords = {} for i=1,10000 do local tb = {} tb.dId = math.random(10000000,999999999) tb.strName = 'name' .. math.random(10000000,999999999) tb.dTest1 = math.random(10000000,999999999) tb.dTest2 = math.random(10000000,999999999) tb.dTest3 = math.random(10000000,999999999) tb.dTest4 = math.random(10000000,999999999) table.insert(tbRecords, tb) end local startTime = os.clock() local str1 = getTable2RecordString1(tbRecords) local endTime = os.clock() print('case1 time used:', endTime - startTime) local startTime = os.clock() local str2 = getTable2RecordString2(tbRecords) local endTime = os.clock() print('case2 time used:', endTime - startTime)

実行結果の例:
------------------------------------- test1 ------------ -------------------------
case1使用時間:0.054
case2使用時間:0.146
------------------------------------- test2 ------------ -------------------------
case1使用時間:0.066
case2使用時間:0.165
------------------------------------- test3 ------------ -------------------------
case1使用時間:1.444
case2使用時間:0.095

  • 概要:特にループで使用する場合は、十分な文字列の連結を行うには、table.concatを使用するのが最適です。
  1. ..のテスト
    1. ワンタイムスプライシング、パフォーマンスに問題ありません
    2. 多数の一時文字が生成され、CPUオーバーヘッドが大きいため、ネストされたループの効率は非常に低くなります。
  2. table.concatの使用
    1. ネストされた文字列の連結、連結のパフォーマンスは優れています。その理由は、luaの最下層がmemcpyを使用してすべてのコンテンツをコピーするためです。
    2. do { /* concat all strings */ size_t l = tsvalue(top-i)->len memcpy(buffer+tl, svalue(top-i), l * sizeof(char)) tl += l } while (--i > 0) setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)) total -= n-1 /* got 'n' strings to create 1 new */ L->top -= n-1 /* popped 'n' strings and pushed one */

パフォーマンス分析の記事: Luaは「..」演算子を最適化しますか?