云峰pbc 库的 lua binding

前几天写的 pbc 初衷就是想可以方便的 binding 到动态语言中去用的。所以今天花了整整一天自己写了个简单的 lua binding 库,就是很自然的工作了。

写完了之后,我很好奇性能怎样,就写了一个非常简单的测试程序测了一下。当然这个测试不说明很多问题,因为测试用的数据实在是太简单了,等明天有空再弄个复杂点的来跑一下吧。我很奇怪,为什么 google 官方的 C++ 版性能这么差。

我的 lua 测试代码大约是这样的:

local protobuf = require "protobuf"

addr = io.open("../../build/addressbook.pb","rb")
buffer = addr:read "*a"
addr:close()
protobuf.register(buffer)

for i=1,1000000 do
    local person = {
        name = "Alice",
        id = 123,
    }
    local buffer = protobuf.encode("tutorial.Person", person)
    local t = protobuf.decode("tutorial.Person", buffer)
end

100 万次的编码和解码在我目前的机器上,耗时 3.8s 。

为了适应性能要求极高的场合,我还提供了另一组高性能 api 。他们可以把数据平坦展开在 lua 栈上,而不构成 table 。只需要把循环里的代码换成

    local buffer = protobuf.pack(
        "tutorial.Person name id",
         "Alice", 123)
    protobuf.unpack("tutorial.Person name id", buffer)

就可以了。这个版本只需要耗时 0.9s 。

一个月前,我曾经自己用 luajit + ffi 实现过一个纯 lua 的版本(没有开源),我跑了一下这个 case ,那个版本也很给力,达到前面的接口的功能,只需要 2.1s 。

不过我相信我新写的 binding 慢主要还是慢在 lua 上, 我换上了 luajit 跑以后,果然快了很多。

table 版本的耗时 1.7s , 平坦展开版是 0.57s.

看来 luajit 的优化力度很大。

btw, 我去年早些时候还写过一个 lua binding ,今天也顺便测了一下,在 luajit 下跑的时间是 1.2s 。没有这次写的这个版本快。

最后,我随手写了一个 C++ 的版本。应该有不少优化途径。不过我想这也是某中常规用法。

<span class="c_Preproc def_Directive" style="color: rgb(0, 128, 115);">#<span class="c_PreprocInclude def_Path def_URI" style="color: rgb(64, 1, 90);">include <span class="c_IncludeOutline def_Outlined def_Special"><span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);"><</span></span>iostream<span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">></span></span></span></span></span>
<span class="c_Preproc def_Directive" style="color: rgb(0, 128, 115);">#<span class="c_PreprocInclude def_Path def_URI" style="color: rgb(64, 1, 90);">include <span class="c_IncludeOutline def_Outlined def_Special"><span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);"><</span></span>sstream<span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">></span></span></span></span></span>
<span class="c_Preproc def_Directive" style="color: rgb(0, 128, 115);">#<span class="c_PreprocInclude def_Path def_URI" style="color: rgb(64, 1, 90);">include <span class="c_IncludeOutline def_Outlined def_Special"><span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);"><</span></span>string<span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">></span></span></span></span></span>
<span class="c_Preproc def_Directive" style="color: rgb(0, 128, 115);">#<span class="c_PreprocInclude def_Path def_URI" style="color: rgb(64, 1, 90);">include <span class="c_IncludeOutline def_Outlined def_Special"><span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">"</span></span>addressbook.pb.h<span class="c_PreprocIncludeEdge def_StringEdge def_String" style="color: rgb(2, 208, 69);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">"</span></span></span></span></span>
<span class="c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">using</span> namespace std<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

<span class="c_KeywordANSI_typenames c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">int</span> <span class="c_FuncOutline def_Outlined def_Special"><span class="c_KeywordLibFunctions def_FunctionKeyword def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">main</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_KeywordANSI_typenames c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">int</span> argc<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">,</span> <span class="c_KeywordANSI_typenames c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">char</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">*</span> argv<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">[</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">]</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span> <span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">{</span></span>
  GOOGLE_PROTOBUF_VERIFY_VERSION<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>


  <span class="c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">for</span> <span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_KeywordANSI_typenames c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">int</span> i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">=</span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">0</span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><</span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">1000000</span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">+</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">+</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span> <span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">{</span></span>
      tutorial<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>Person person<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

      person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>set_name<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_String def_String" style="color: rgb(0, 196, 196);">"Alice"</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
      person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>set_id<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">123</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

      stringstream output<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

      person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>SerializeToOstream<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">&</span>output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
      output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>str<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
      tutorial<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>Person person2<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

      person2<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>ParseFromIstream<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">&</span>output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

      person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>name<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
      person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>id<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
  <span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">}</span></span>

  google<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>protobuf<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>ShutdownProtobufLibrary<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

  <span class="c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">return</span> <span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">0</span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
<span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">}</span></span>

这段代码在开了 -O2 编译后,在我的机器上依旧需要时间 1.9s。若是这么看,那简直是太慢了 (比 luajit + c binding 还慢)。很久没研究 C++ 的细节,也懒得看了,如果谁有兴趣研究一下为什么 C++ 这么慢,我很有兴趣知道原因。


12 月 16 日

留言中 lifc0 说这段 C++ 代码中开销最大的是 stringstream 的构造和销毁, 所以我改了一段代码:

stringstream output<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
stringstream input<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

<span class="c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">for</span> <span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_KeywordANSI_typenames c_KeywordANSI def_Keyword" style="color: rgb(230, 97, 112); font-weight: bold;">int</span> i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">=</span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">0</span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><</span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">1000000</span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>i<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">+</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">+</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span> <span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">{</span></span>
    output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>clear<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
    output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>str<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_String def_String" style="color: rgb(0, 196, 196);">""</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    tutorial<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>Person person<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
    person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>set_name<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_String def_String" style="color: rgb(0, 196, 196);">"Alice"</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
    person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>set_id<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="def_NumberDec def_Number" style="color: rgb(0, 140, 0);">123</span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    person<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>SerializeToOstream<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">&</span>output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    input<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>clear<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
    input<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>str<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span>output<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>str<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    tutorial<span class="c_PrefixSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">::</span>Person person2<span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    person2<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>ParseFromIstream<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">&</span>input<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>

    person2<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>name<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
    person2<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);">.</span>id<span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairStart def_Special" style="color: rgb(170, 68, 68);">(</span></span><span class="c_Symbol def_Symbol" style="color: rgb(107, 102, 39);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);">;</span>
<span class="def_SymbolStrong def_Symbol" style="color: rgb(176, 96, 176);"><span class="def_PairEnd def_Special" style="color: rgb(170, 68, 68);">}</span></span>

这样更符合现实应用, 每次初始化 stringstream 而不构造新的出来.

这样运行时间就从 1.90s 下降到 1.18s 了.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值