luafan

fan.objectbuf

objectbuf is used to serialize lua object to string, and deserialize string to lua object.

lua object type supported

table, string, number, boolean

why not cjson

Notice

objectbuf may a little slow than cjson on small lua object, but it is faster than cjson on huge lua object.

encode format

flag (int8) describe whether stream contains number/integer/string/table section, if there is no number/integer/string/table section, the lowest bit of flag is used to describe boolean value 1 => true, 0 => false.

Each section start with a u30(fan.stream) value to describe the count of number/integer/string/table inside the section.

there is a builtin index dictionary:

APIs

sym = objectbuf.symbol(sample:table)

build symbol table for object to encode/decode to reduce output data size.

data = objectbuf.encode(obj:object, sym?)

encode lua object to string.

obj = objectbuf.decode(data:string, sym?)

decode lua object from string.

Benchmark

benchmark server

Linux XXXXXX 4.4.0-70-generic #91-Ubuntu SMP Wed Mar 22 12:47:43 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz

MemTotal:        3922816 kB
LUA Version Name Time Cost (sec)
luajit objectbuf 1.7200319766998
luajit objectbuf + sym 0.5656890869140
luajit cjson 7.1654288768768
objectbuf.encode	1.2554931640625
objectbuf.decode	0.46449613571167
objectbuf
	1.7200319766998
objectbuf.encode_sym	0.49760103225708
objectbuf.decode_sym	0.068063020706177
objectbuf.sym
	0.56568908691406
cjson.encode	3.6382949352264
cjson.decode	3.5271048545837
cjson
	7.1654288768768
LUA Version Name Time Cost (sec)
lua5.3 objectbuf 2.3849251270294
lua5.3 objectbuf + sym 0.7837250232696
lua5.3 cjson 7.8768520355225
objectbuf.encode	1.9406111240387
objectbuf.decode	0.44426012039185
objectbuf
	2.3849251270294
objectbuf.encode_sym	0.69732403755188
objectbuf.decode_sym	0.086374998092651
objectbuf.sym
	0.78372502326965
cjson.encode	4.0115370750427
cjson.decode	3.8652799129486
cjson
	7.8768520355225
require "compat53"

local objectbuf = require "fan.objectbuf"
local fan = require "fan"
local utils = require "fan.utils"
local cjson = require "cjson"

local a = {
    b = {
        1234556789,
        12345.6789,
        nil,
        -1234556789,
        -12345.6789,
        0,
        "asdfa",
        d = {
            e = f
        }
    },
    averyvery = "long long textlong long textlong long textlong long textlong long textlong long textlong long textlong long textlong long textlong long textlong long textlong long text",
}

-- cjson does not support this.
-- a.b.a = a

-- set same random seed for benchmark.
math.randomseed(0)

for i=1,100 do
    table.insert(a.b, string.rep("abc", math.random(1000)))
end

local sym = objectbuf.symbol(a)

local loopcount = 10000

local data = objectbuf.encode(a)
local data_sym = objectbuf.encode(a, sym)
local data_json = cjson.encode(a)

local start = utils.gettime()
for i=1,loopcount do
    objectbuf.encode(a)
end
print("objectbuf.encode", utils.gettime() - start)

local start2 = utils.gettime()
for i=1,loopcount do
    objectbuf.decode(data)
end
print("objectbuf.decode", utils.gettime() - start2)
print("objectbuf\n", utils.gettime() - start)

local start = utils.gettime()
for i=1,loopcount do
    objectbuf.encode(a, sym)
end
print("objectbuf.encode_sym", utils.gettime() - start)

local start2 = utils.gettime()
for i=1,loopcount do
    objectbuf.decode(data_sym, sym)
end
print("objectbuf.decode_sym", utils.gettime() - start2)
print("objectbuf.sym\n", utils.gettime() - start)

local start = utils.gettime()
for i=1,loopcount do
    cjson.encode(a)
end
print("cjson.encode", utils.gettime() - start)

local start2 = utils.gettime()
for i=1,loopcount do
    cjson.decode(data_json)
end
print("cjson.decode", utils.gettime() - start2)
print("cjson\n", utils.gettime() - start)

os.exit()