@Marja , According to your suggestion, I updated the test case with more 
random string access instead of const string. The new result is that CPP 
test case performs 2~3 times slower than JS test case now.

I posted more detail information at the end of  
https://github.com/cocos/cocos-engine/issues/12878  here .

2~3 times slower is still not good enough for us to switch deserialization 
logic from JS to CPP. 
So, is 2~3 times slower expected ? Or are there more things I could do?

> In addition to what Marja said, I assume that a significant difference 
(even without JIT) is that JavaScript can use Inline Caches, whereas the 
API cannot.

@Jakob, Thank you for pointing me out that inline caches also make some 
optimizations.


在2022年10月17日星期一 UTC+8 17:54:34<Jakob Kummerow> 写道:

> In addition to what Marja said, I assume that a significant difference 
> (even without JIT) is that JavaScript can use Inline Caches, whereas the 
> API cannot.
>
>
> On Mon, Oct 17, 2022 at 10:34 AM James Chen <dumg...@gmail.com> wrote:
>
>> Got it. I would modify my test code to see whether the result  could get 
>> better.
>>
>> Thanks for your reply. :)
>>
>> 在2022年10月17日星期一 UTC+8 13:59:35<ma...@chromium.org> 写道:
>>
>>> Hi,
>>>
>>> I didn't have a deep look, but your benchmarking might not be 
>>> representative. 
>>>
>>> 1) V8 probably optimizes such a tight loop a lot (in the JIT mode). 
>>> You're using string constants as property names, and V8 sees the whole 
>>> object creation code at once, and can generate better optimized code. When 
>>> we only need to do one v8::Object::Set, we can't do the same optimizations. 
>>> (Very hand-wavy explanation; I didn't look at the actual generated code in 
>>> this case.) If you make the object shape and property names + values more 
>>> unpredictable (also if you make the benchmark closer to what your actual 
>>> deserializer does), you might see a smaller difference. You'll also need to 
>>> take into account the time needed for V8 to parse + compile the code, not 
>>> only the JS execution time.
>>>
>>> 2) The string creation (for the property names) is done when we parse 
>>> the JS code, so it's outside your benchmark timer. In your C++ version, I 
>>> assume it's inside your benchmark timer.
>>>
>>> The "16 times faster in the non-JIT mode" is a bit high though, I 
>>> would've guessed the difference would be smaller.
>>>
>>> Cheers,
>>>
>>> On Mon, Oct 17, 2022 at 4:12 AM James Chen <dumg...@gmail.com> wrote:
>>>
>>>> Hello V8 team, thanks for making V8 engine which could run JavaScript 
>>>> super fast.
>>>>
>>>> Recently, I want to improve the performance of deserialization for 
>>>> Cocos Creator game engine.
>>>>
>>>> Cocos Creator uses V8 for its default JavaScript engine and benefited 
>>>> from V8's high performance. There're many classes implemented in JS and 
>>>> some implemented in C++. And there will be more and more JS code moved to 
>>>> C++ side.
>>>>
>>>> I thought about deserializing game assets directly in C++ rather than 
>>>> in JS to get better performance since I think C++ code should be faster.
>>>>
>>>> Therefore, I wrote a testcase to test whether we could get benefited 
>>>> from C++ code. But unfortunately, I got a really bad result saying that 
>>>> create JS object and setting properties in C++ by V8 API is really slower 
>>>> than doing that in JS. It's about 50 times slower, in another word, JS 
>>>> execution is really fast.
>>>>
>>>> I debugged a little bit and found that the most heavy cost is in 
>>>> v8::Object::Set and v8::String::NewFromUtf8.
>>>>
>>>> Part of JS test code:
>>>> const testArr = new Array<MySerializationTestClass>(this.loopCount);
>>>>         const start = performance.now();
>>>>
>>>>         for (let i = 0; i < this.loopCount; ++i) {
>>>>             const test = new MySerializationTestClass();
>>>>             testArr[i] = test;
>>>>
>>>>             test['booleanValue'] = false;
>>>>             test['nullValue'] = null;
>>>>             test['undefinedValue'] = undefined;
>>>>             test['numberValue0'] = 100.123;
>>>>             test['numberValue1'] = 230.2345;
>>>>             test['numberValue2'] = 330.2345;
>>>>             test['numberValue3'] = 430.2345;
>>>>             test['numberValue4'] = 530.2345;
>>>>
>>>>             test['stringValue0'] = 'hello 0';
>>>>
>>>>             test['stringValue1'] = 'hello 1';
>>>>
>>>> The logic of CPP test code is the same as which in the above JS test 
>>>> code. The difference is that we use v8::Object::Set API.
>>>>
>>>> ### JIT Enabled
>>>>
>>>> Cpp code is 55 times slower than JS code.
>>>>
>>>> ### JIT Disabled
>>>>
>>>> Cpp code is 16 times slower than JS code.
>>>>
>>>>
>>>> ### Xcode Profile
>>>>
>>>>
>>>> `v8::Maybe<bool> ret = 
>>>> _obj.handle(__isolate)->Set(__isolate->GetCurrentContext(), 
>>>> nameValue.ToLocalChecked(), value);` and `v8::String::NewFromUtf8` are the 
>>>> main hotspots.
>>>>
>>>> ### What I guess
>>>>
>>>> I guess running JS code directly could make use of the optimization by 
>>>> V8 Bytecode and JIT by TurboFan. But invoking V8 C++ API will not get the 
>>>> optimization. 
>>>>
>>>>
>>>> Could you point me out that whether my guess is correct or not? Also, 
>>>> is there a better V8 API for setting property?  Thanks.
>>>>
>>>

-- 
-- 
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
--- 
You received this message because you are subscribed to the Google Groups 
"v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/v8-dev/efc01cf2-8383-4034-abff-5a0d2cc54bd4n%40googlegroups.com.

Reply via email to