三种方式
1、serialize1和deseralize1是将数据在c++反序列化为c++的结构体,将该结构体传给lua,lua里面操作该结构体,结束后c++序列化该结构体
2、seralize2和deseralize2是将数据传给lua,lua反序列化成lua的结构,lua再操作该结构,结束后,lua序列化,然后再返回给c++
3、seralize3和deseralize3是将数据在c++反序列化后,将数据初始化为lua里面的结构体,lua操作lua自己的结构体,结束后,返回lua结构体,c++根据这个结构体再序列化
参考文档
[https://www.lua.org/pil/contents.html#P4]
编译执行
编译:g++ test.cpp -llua
执行:sh -x test.sh 1000000
结论:
结果:3>1>2
lua里面操作自己的结果比操作c++里面的结果会更高效
test.cpp
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <cstring>
#include <string>
#include <stdint.h>
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
using namespace std;
class A {
public:
A()
{
}
~A()
{
}
void dump() const
{
printf("c++: A::dump(), m_x0 = %d,m_y0 = %d \n", m_x0,m_y0);
}
static void reg(lua_State *L);
public:
static A *check(lua_State *L);
static int L_dump(lua_State *L);
static int L_setval(lua_State *L);
static int L_getval(lua_State *L);
static int L_tostring(lua_State *L);
public:
void show()
{
std::cout << "c++ m_x0:" << m_x0 << std::endl;
std::cout << "c++ m_y0:" << m_y0 << std::endl;
std::cout << "c++ m_x1:" << m_x1 << std::endl;
std::cout << "c++ m_y1:" << m_y1 << std::endl;
std::cout << "c++ m_x2:" << m_x2 << std::endl;
std::cout << "c++ m_y2:" << m_y2 << std::endl;
std::cout << "c++ m_x3:" << m_x3 << std::endl;
std::cout << "c++ m_y3:" << m_y3 << std::endl;
}
void serialize(string& buff)
{
ostringstream oss;
oss << m_x0 << ":";
oss << m_y0 << ":";
oss << m_x1 << ":";
oss << m_y1 << ":";
oss << m_x2 << ":";
oss << m_y2 << ":";
oss << m_x3 << ":";
oss << m_y3 << ":";
buff = oss.str();
}
void deserialize(const string& buff)
{
size_t pos_begin = 0;
size_t pos_end = buff.find(":", pos_begin);
m_x0 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_y0 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_x1 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_y1 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_x2 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_y2 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_x3 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
pos_begin = pos_end + 1;
pos_end = buff.find(":", pos_begin);
m_y3 = atol(buff.substr(pos_begin, pos_end - pos_begin).c_str());
}
public:
int m_x0;
int m_y0;
int m_x1;
int m_y1;
int m_x2;
int m_y2;
int m_x3;
int m_y3;
};
using namespace std;
void print_stack(lua_State* state, const char* msg)
{
int top = lua_gettop(state);
for (int index = top; index > 0; --index)
{
int type = lua_type(state, index);
cout << "index:" << index << " type:" << type << " name:" << lua_typename(state, type) << endl;
}
cout << "----------------------------" << msg << endl;
}
// lua operator struct, c++ serialize this struct
void do_serialize1(lua_State* L, uint32_t count)
{
string buff = "1:2:3:4:5:6:7:8:";
A a;
a.deserialize(buff);
for (uint32_t i = 0; i < count; ++i)
{
A data = a;
lua_getglobal(L,"serialize1");
lua_pushlightuserdata(L,&data);
int val = lua_gettop(L);
lua_getfield(L, LUA_REGISTRYINDEX, "A");
lua_pushliteral(L, "__index");
lua_gettable(L,-2);
lua_pop(L,1);
lua_setmetatable(L, val);
if(lua_pcall( L, 1, 0, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
getchar();
exit(0);
}
string buffer;
data.serialize(buffer);
#ifdef PRINT
data.show();
#endif
}
}
// c++ deserialize,lua operator this struct
void do_deserialize1(lua_State* L, uint32_t count)
{
string buff = "1:2:3:4:5:6:7:8:";
for (uint32_t i = 0; i < count; ++i)
{
A data;
data.deserialize(buff);
lua_getglobal(L,"deserialize1");
lua_pushlightuserdata(L,&data);
int val = lua_gettop(L);
lua_getfield(L, LUA_REGISTRYINDEX, "A");
lua_pushliteral(L, "__index");
lua_gettable(L,-2);
lua_pop(L,1);
lua_setmetatable(L, val);
if(lua_pcall( L, 1, 0, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
getchar();
exit(0);
}
#ifdef PRINT
data.show();
#endif
}
}
// lua serialize
void do_serialize2(lua_State* L, uint32_t count)
{
string buff = "1:2:3:4:5:6:7:8:";
A a;
a.deserialize(buff);
for (uint32_t i = 0; i < count; ++i)
{
A data = a;
lua_getglobal(L,"serialize2");
lua_pushlightuserdata(L,&data);
int val = lua_gettop(L);
lua_getfield(L, LUA_REGISTRYINDEX, "A");
lua_pushliteral(L, "__index");
lua_gettable(L,-2);
lua_pop(L,1);
lua_setmetatable(L, val);
if (lua_pcall( L, 1, 1, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
getchar();
exit(0);
}
#ifdef PRINT
A ret;
ret.deserialize(lua_tostring(L, -1));
ret.show();
#endif
lua_pop(L, 1);
}
}
void do_deserialize2(lua_State* L, uint32_t count)
{
for (uint32_t i = 0; i < count; ++i)
{
string buff = "1:2:3:4:5:6:7:8:";
lua_getglobal(L,"deserialize2");
lua_pushstring(L, buff.c_str());
if(lua_pcall( L, 1, 1, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
getchar();
exit(0);
}
#ifdef PRINT
A a;
a.deserialize(lua_tostring(L, -1));
a.show();
#endif
lua_pop(L, 1);
}
}
void get_data_from_lua(lua_State* L, A& data)
{
lua_getfield(L, -1, "m_x0");
data.m_x0 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_y0");
data.m_y0 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_x1");
data.m_x1 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_y1");
data.m_y1 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_x2");
data.m_x2 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_y2");
data.m_y2 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_x3");
data.m_x3 = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "m_y3");
data.m_y3 = lua_tonumber(L, -1);
lua_pop(L, 1);
}
void set_data_to_lua(lua_State* L ,const A& data)
{
lua_pushliteral(L, "m_x0");
lua_pushnumber(L, data.m_x0);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_y0");
lua_pushnumber(L, data.m_y0);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_x1");
lua_pushnumber(L, data.m_x1);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_y1");
lua_pushnumber(L, data.m_y1);
lua_rawset(L, -3);
lua_pushliteral(L, "m_x2");
lua_pushnumber(L, data.m_x2);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_y2");
lua_pushnumber(L, data.m_y2);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_x3");
lua_pushnumber(L, data.m_x3);
lua_rawset(L, -3);
lua_getglobal(L,"data");
lua_pushliteral(L, "m_y3");
lua_pushnumber(L, data.m_y3);
lua_rawset(L, -3);
}
void do_serialize3(lua_State*L, uint32_t count)
{
string buff = "1:2:3:4:5:6:7:8:";
A data;
data.deserialize(buff);
for (uint32_t i = 0; i < count; ++i)
{
lua_getglobal(L,"data");
set_data_to_lua(L, data);
lua_getglobal(L,"serialize3");
if(lua_pcall( L, 0, 1, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
std::cout << "call failed" << std::endl;
continue;
}
A data;
get_data_from_lua(L, data);
lua_pop(L, 1);
string buff;
data.serialize(buff);
#ifdef PRINT
data.show();
#endif
}
}
void do_deserialize3(lua_State*L, uint32_t count)
{
string buff = "1:2:3:4:5:6:7:8:";
for (uint32_t i = 0; i < count; ++i)
{
lua_getglobal(L,"data");
A data;
data.deserialize(buff);
set_data_to_lua(L, data);
lua_getglobal(L,"deserialize3");
if(lua_pcall( L, 0, 1, 0 ) != 0)
{
const char *str = lua_tostring(L,-1);
std::cout << str <<std::endl;
lua_close( L );
std::cout << "call failed" << std::endl;
continue;
}
#ifdef PRINT
A ret;
get_data_from_lua(L, ret);
ret.show();
#endif
lua_pop(L, 1);
}
}
int main(int argc, char* argv[])
{
if (argc < 4)
{
cout << "useage: ./a.out times serialize(0)|deserialize(1) type(1|2|3)" << endl;
return 0 ;
}
lua_State *L;
if ((L = lua_open()) == NULL) {
printf("failed to create lua state!/n");
return 0;
}
luaL_openlibs(L);
A::reg(L);
if (luaL_dofile(L, "main.lua")) {
printf("%s!/n", lua_tostring(L, -1));
lua_close(L);
return 0;
}
uint32_t count = atol(argv[1]);
if (atol(argv[3]) == 1)
{
if (atol(argv[2]) == 0)
do_serialize1(L, count);
else
do_deserialize1(L, count);
}
else if (atol(argv[3]) == 2)
{
if (atol(argv[2]) == 0)
do_serialize2(L, count);
else
do_deserialize2(L, count);
}
else if (atol(argv[3]) == 3)
{
if (atol(argv[2]) == 0)
do_serialize3(L, count);
else
do_deserialize3(L, count);
}
lua_close(L);
return 0;
}
void A::reg(lua_State *L)
{
lua_newtable(L);
int methods = lua_gettop(L);
lua_pushliteral(L, "dump");
lua_pushcfunction(L, &A::L_dump);
lua_rawset(L, methods);
lua_pushliteral(L, "m_x0");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_y0");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_x1");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_y1");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_x2");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_y2");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_x3");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
lua_pushliteral(L, "m_y3");
lua_pushnumber(L, 0);
lua_rawset(L, methods);
luaL_newmetatable(L, "A");
int mt = lua_gettop(L);
lua_pushliteral(L, "__index");
lua_pushcfunction(L, &A::L_getval);
lua_rawset(L, mt);
lua_pushliteral(L, "__newindex");
lua_pushcfunction(L, &A::L_setval);
lua_rawset(L, mt);
lua_pushliteral(L, "__tostring");
lua_pushcfunction(L, &A::L_tostring);
lua_rawset(L, mt);
lua_newtable(L);
int A = lua_gettop(L);
lua_pushvalue(L, methods);
lua_setmetatable(L, A);
lua_setglobal(L, "A");
}
A *A::check(lua_State *L)
{
A *a;
a = (A *)luaL_checkudata(L, 1, "A");
lua_remove(L, 1);
return a;
}
int A::L_dump(lua_State *L)
{
A *self;
self = A::check(L);
self->dump();
return 0;
}
int A::L_getval(lua_State *L)
{
A *self;
int val;
self = (A *)luaL_checkudata(L, 1, "A");
lua_getfield(L, LUA_REGISTRYINDEX, "A");
lua_pushliteral(L, "__index");
lua_gettable(L,-2);
const char *tmp = luaL_checkstring(L, -3);
if (strcmp("m_x0", tmp) == 0)
{
lua_pushnumber(L, self->m_x0);
}
else if (strcmp("m_y0", tmp) == 0)
{
lua_pushnumber(L, self->m_y0);
}
else if (strcmp("m_x1", tmp) == 0)
{
lua_pushnumber(L, self->m_x1);
}
else if (strcmp("m_y1", tmp) == 0)
{
lua_pushnumber(L, self->m_y1);
}
else if (strcmp("m_x2", tmp) == 0)
{
lua_pushnumber(L, self->m_x2);
}
else if (strcmp("m_y2", tmp) == 0)
{
lua_pushnumber(L, self->m_y2);
}
else if (strcmp("m_x3", tmp) == 0)
{
lua_pushnumber(L, self->m_x3);
}
else if (strcmp("m_y3", tmp) == 0)
{
lua_pushnumber(L, self->m_y3);
}
return 1;
}
int A::L_setval(lua_State *L)
{
A *self;
int val;
self = (A *)luaL_checkudata(L, 1, "A");
lua_getfield(L, LUA_REGISTRYINDEX, "A");
lua_pushliteral(L, "__index");
lua_gettable(L,-2);
val = luaL_checkint(L, -3);
const char *tmp = luaL_checkstring(L, -4);
if(strcmp("m_y0", tmp) == 0)
{
self->m_y0 = val;
lua_pushnumber(L, self->m_y0);
lua_setfield(L, -3, "m_y0");
}
else if(strcmp("m_x1", tmp) == 0)
{
self->m_x1 = val;
lua_pushnumber(L, self->m_x1);
lua_setfield(L, -3, "m_x1");
}
else if(strcmp("m_y1", tmp) == 0)
{
self->m_y1 = val;
lua_pushnumber(L, self->m_y1);
lua_setfield(L, -3, "m_y1");
}
else if(strcmp("m_x2", tmp) == 0)
{
self->m_x2 = val;
lua_pushnumber(L, self->m_x2);
lua_setfield(L, -3, "m_x2");
}
else if(strcmp("m_y2", tmp) == 0)
{
self->m_y2 = val;
lua_pushnumber(L, self->m_y2);
lua_setfield(L, -3, "m_y2");
}
else if(strcmp("m_x3", tmp) == 0)
{
self->m_x3 = val;
lua_pushnumber(L, self->m_x3);
lua_setfield(L, -3, "m_x3");
}
else if(strcmp("m_y3", tmp) == 0)
{
self->m_y3 = val;
lua_pushnumber(L, self->m_y3);
lua_setfield(L, -3, "m_y3");
}
else if(strcmp("m_x0", tmp) == 0)
{
self->m_x0 = val;
lua_pushnumber(L, self->m_x0);
lua_setfield(L, -3, "m_x0");
}
lua_pop(L,1);
lua_setmetatable(L, val);
return 0;
}
int A::L_tostring(lua_State *L)
{
A *self;
self = A::check(L);
char buff[1024] = {0};
sprintf(buff, "m_x0 = %d, m_y0 = %d, m_x = %d, m_y1 = %d, m_x2 = %d, m_y2 = %d, m_x3 = %d, m_y3 = %d", self->m_x0, self->m_y0, self->m_x1, self->m_y1, self->m_x2, self->m_y2, self->m_x3, self->m_y3);
lua_pushfstring(L, "C++: A::to_string(), %s", buff);
return 1;
}
main.lua
function serialize1(a)
a.m_x0 = a.m_x0 + 1
a.m_y0 = a.m_y0 + 1
a.m_x1 = a.m_x1 + 1
a.m_y1 = a.m_y1 + 1
a.m_x2 = a.m_x2 + 1
a.m_y2 = a.m_y2 + 1
a.m_x3 = a.m_x3 + 1
a.m_y3 = a.m_y3 + 1
-- print(a)
end
function deserialize1(a)
a.m_x0 = a.m_x0 + 1
a.m_y0 = a.m_y0 + 1
a.m_x1 = a.m_x1 + 1
a.m_y1 = a.m_y1 + 1
a.m_x2 = a.m_x2 + 1
a.m_y2 = a.m_y2 + 1
a.m_x3 = a.m_x3 + 1
a.m_y3 = a.m_y3 + 1
--print(a)
end
function serialize2(data)
data.m_x0 = 9
buff = data.m_x0 ..":" .. data.m_y0 ..":".. data.m_x1 ..":".. data.m_y1 ..":".. data.m_x2 ..":".. data.m_y2 ..":".. data.m_x3 ..":".. data.m_y3 ..":"
return buff
end
function deserialize2(str)
begin_pos = 1
end_pos = string.find(str,':', begin_pos)
x0 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos )
y0 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
x1 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
y1 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
x2 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
y2 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
x3 = string.sub(str, begin_pos, end_pos -1)
begin_pos = end_pos + 1
end_pos = string.find(str,':', begin_pos)
y3 = string.sub(str, begin_pos, end_pos -1)
x0 = 9
--print(" x0=" .. x0 .. " y0="..y0.. " x1=".. x1.. " y1=" .. y1 .. " x2=" .. x2 .. " y2=".. y2 .. " x3=" .. x3 .. " y3=" ..y3)
return str
end
data = {
m_x0 = 9,
m_y0 = 10,
m_x1 = 11,
m_y1 = 12,
m_x2 = 13,
m_y2 = 14,
m_x3 = 15,
m_y3 = 16
};
function serialize3()
data.m_x0 = data.m_x0 + 9
data.m_y0 = data.m_y0 + 10
data.m_x1 = data.m_x1 + 11
data.m_y1 = data.m_y1 + 12
data.m_x2 = data.m_x2 + 13
data.m_y2 = data.m_y2 + 14
data.m_x3 = data.m_x3 + 15
data.m_y3 = data.m_y3 + 16
return data;
end
--
function deserialize3()
data.m_x0 = 9
data.m_y0 = 10
data.m_x1 = 11
data.m_y1 = 12
data.m_x2 = 13
data.m_y2 = 14
data.m_x3 = 15
data.m_y3 = 16
return data;
end
test.sh
#!/bin/bash
time ./a.out $1 0 1
time ./a.out $1 1 1
time ./a.out $1 0 2
time ./a.out $1 1 2
time ./a.out $1 0 3
time ./a.out $1 1 3