lua c 交互性能对比

三种方式

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358