[心情] 💢 分享一段性能只有原生1/15的addons
发布于 9 年前 作者 MiguelValentine 4696 次浏览 最后一次编辑是 8 年前 来自 分享
void Tools::Upxcore(Handle<Value>& value,std::string& str){
    if(value->IsArray()){
        str += "[";
        Array* arr = Array::Cast(*value);
        int len = arr->Length();
        for( int a = 0; a < len; a = a + 1 )
        {
            Handle<Value>nvalue = arr->Get(a);
            Upxcore(nvalue,str);
            if(a != len-1){
                str += ',';
            }
        }
        str +="]";
    }else if(value->IsObject()){
        str += "{";
        Local<Object> obj = value->ToObject();
        Local<Array> key_arr = obj->GetPropertyNames();
        int len = key_arr->Length();
        for( int a = 0; a < len; a = a + 1 )
        {
            Handle<Value>nkey = key_arr->Get(a);
            Handle<Value>nvalue = obj->Get(nkey);
            Upxcore(nkey,str);
            str += ":";
            Upxcore(nvalue,str);
            if(a != len-1){
                str += ',';
            }
        }
        str += "}";
    }else if(value->IsString()){
        String::Utf8Value keyUtf8Value(value);
        std::string keyString = std::string(*keyUtf8Value);
        str += "\""+keyString+"\"";
    }
    return;
}

看到这段代码的时候我已经在改汇编了- -

7 回复

标题 表达有误吧, 是要理解成 原生性能是你的代码的15倍?

@dayuoba 没错。今天写了个废物函数- -

这样的代码,效率高就奇怪了,问题出在str+上面,这样做字符串拷贝神仙也救不了啊,无谓的内存分配,内存拷贝。 为了说明低效的原因,我们假设str一开始预分配了16字节的内存,往里面加内容,加到超过16字节,再分配一个32字节的,将原来的那个拷贝过来,继续往里面加,再超过,再分配48字节,继续拷贝原来的,如此循环下去,碰到不够的地方就要做无谓的内存分配,释放和拷贝,这样的程序效率能高么?

你这种情况简单的优化是估算出字符串大小,然后直接分配一个大内存,直接往里拷贝数据,这样就避免的无谓的内存分配,释放和拷贝。C++虽然效率很高,但是内存分配和拷贝代价是很大的,CPU的运算速度是访问内存速度的10几倍啊。

能用原生的就不要自己造了,方法不对,汇编也救不了你。

@coordcn 说的好!可是我本来就是会汇编不会c/c++ - -

@coordcn 我试试能不能做l2/l3/mem 优化

@MiguelValentine 建议先看下v8的string_builder实现

他的内存开始是32字节,然后每次翻倍,还做个分块处理,每块最大16×1024

源代码下无秘密,自己实现一个string_builder效率就上去了。但还是建议用原生的,原生的考虑的比较周全,尤其在安全上面。原生的也基本都是C++代码了,效率上可提升的有限。学原理玩玩可以,工程上还是现实点。

你蛮喜欢折腾的嘛,我现在有个自己的项目,lua和libuv实现形式同步,有兴趣可以来一起完善,交流。

https://github.com/coordcn/links

C++ 版 JSON.stirngify么?

回到顶部