iOS javascript slow performance (and significant increase of memory)

Hi,

I have created simple fuse project to reorder a list with swipe gesture in a puzzle like style

[https://github.com/zean00/fuse-swipeorder-sample]

There are a code that do the switch of two item by removing and inserting item on the list to reorder

function switchPos(currentPos,targetPos,direction){
     var targetItem = items.getAt(targetPos);
     var currentItem = items.getAt(currentPos);
     targetItem.pos.value = currentPos;
     currentItem.pos.value = targetPos;

     currentItem.moveX.value = currentItem.moveY.value = 0;
     if(direction==='right'){
        targetItem.moveX.value = 1;
        targetItem.moveY.value = 0;
     }
     if(direction==='left'){
        targetItem.moveX.value = -1;
        targetItem.moveY.value = 0;
     }
     if(direction==='up'){
        targetItem.moveY.value = -1;
        targetItem.moveX.value = 0;
     }
     if(direction==='down'){
         targetItem.moveY.value = 1;
         targetItem.moveX.value = 0;
     }

     items.removeAt(currentPos);
     items.insertAt(currentPos,targetItem);
     items.removeAt(targetPos);
     items.insertAt(targetPos,currentItem);

     return currentItem;
  }

This solution work fine on Android and local preview, they behave similar in term of performance and response. But surprisingly, this app seems very slow in a performance in iOS (both in preview and export, and either in device or simulator), the are noticeable delay when the switching process is done compared to android and local preview (the animation flawlessly smooth though)

And more surprisingly, the resource monitor tells that whenever the switch function is in process, the processor spike to almost 100% and the memory is increasing and not significantly lowering back. The apps start with just 20MB memory consumption, and could reach to 200MB for several switching operation and stays around that. Compared to Android preview, it’s just took 30% of CPU at max and less than 10MB of memory.

I’m not sure if this issue is related to Huge memory consumption running asm.js on iOS that I’ve been reported https://www.fusetools.com/community/forums/bug_reports/huge_memory_consumption_on_ios_while_loading_javas?page=1

This is the profiling data I gather from running the apps with simulator

Bytes Used    Count        Symbol Name
 104.19 MB      48.2%    1213449         thread_start
 104.19 MB      48.2%    1213449          _pthread_start
 104.19 MB      48.2%    1213449           _pthread_body
 104.16 MB      48.2%    1213422            invoke_delegate(void*)
 103.14 MB      47.7%    1213421             uDelegate::InvokeVoid()
 103.14 MB      47.7%    1213421              g::Uno::Threading::POSIXThread__ReleasingLauncher__Run_fn(g::Uno::Threading::POSIXThread__ReleasingLauncher*)
 103.14 MB      47.7%    1213421               g::Uno::Threading::POSIXThread__ReleasingLauncher::Run()
 103.14 MB      47.7%    1213421                uDelegate::InvokeVoid()
 103.14 MB      47.7%    1213421                 g::Fuse::Reactive::ThreadWorker__Run_fn(g::Fuse::Reactive::ThreadWorker*)
 103.14 MB      47.7%    1213421                  g::Fuse::Reactive::ThreadWorker::Run()
 102.23 MB      47.3%    1211434                   uDelegate::InvokeVoid()
 102.23 MB      47.3%    1211434                    g::Fuse::Reactive::EventBinding__CallClosure__Call_fn(g::Fuse::Reactive::EventBinding__CallClosure*)
 102.23 MB      47.3%    1211434                     g::Fuse::Reactive::EventBinding__CallClosure::Call()
 102.22 MB      47.3%    1211323                      g::Fuse::Scripting::Function::Call(uArray*)
 102.22 MB      47.3%    1211323                       g::Fuse::Scripting::JavaScriptCore::Function__Call_fn(g::Fuse::Scripting::JavaScriptCore::Function*, uArray*, uObject**)
 102.22 MB      47.3%    1211323                        g::Fuse::Scripting::JavaScriptCore::JSValue::CallWithArguments(uObject*, uArray*)
 102.22 MB      47.3%    1211323                         g::Fuse::Scripting::JavaScriptCore::JSValue::CallWithArguments(uObject*, uArray*)::$_0::operator()(objc_object*, id<UnoArray>) const
 102.22 MB      47.3%    1211323                          -[JSValue callWithArguments:]
 102.22 MB      47.3%    1211323                           JSObjectCallAsFunction
 102.22 MB      47.3%    1211323                            JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&)
 102.22 MB      47.3%    1211323                             JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&)
 102.22 MB      47.3%    1211323                              JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*)
 102.22 MB      47.3%    1211323                               vmEntryToJavaScript
 102.22 MB      47.3%    1211323                                llint_entry
 102.22 MB      47.3%    1211323                                 llint_entry
  96.59 MB      44.7%    1143210                                  llint_entry
  64.24 MB      29.7%    737820                                   0x7ddd0695689
  64.24 MB      29.7%    737820                                    0x7dd906a4c2b
  64.24 MB      29.7%    737811                                     0x7dd9069bdb4
  64.24 MB      29.7%    737811                                      operationVirtualCall
  64.24 MB      29.7%    737811                                       JSC::handleHostCall(JSC::ExecState*, JSC::JSValue, JSC::CodeSpecializationKind)
  64.24 MB      29.7%    737811                                        long long JSC::APICallbackFunction::call<JSC::ObjCCallbackFunction>(JSC::ExecState*)
  64.24 MB      29.7%    737811                                         JSC::objCCallbackFunctionCallAsFunction(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**)
  63.99 MB      29.6%    737808                                          JSC::ObjCCallbackFunctionImpl::call(JSContext*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**)
 192.00 KB       0.0%    2                                          objc_autoreleasePoolPop
  64.00 KB       0.0%    1                                          -[JSContext(Internal) endCallbackWithData:]

And here it is the list of heaviest stack trace

  46 libsystem_pthread.dylib  104.19 MB     thread_start
  44 libsystem_pthread.dylib  104.19 MB     _pthread_body
  43 fuse-swipeorder-sample  104.16 MB     invoke_delegate(void*) include/posix_thread.h:15
  32 fuse-swipeorder-sample  102.22 MB     g::Fuse::Scripting::JavaScriptCore::Function__Call_fn(g::Fuse::Scripting::JavaScriptCore::Function*, uArray*, uObject**) /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.g.cpp:390
  31 fuse-swipeorder-sample  102.22 MB     g::Fuse::Scripting::JavaScriptCore::JSValue::CallWithArguments(uObject*, uArray*) /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:214
  30 fuse-swipeorder-sample  102.22 MB     g::Fuse::Scripting::JavaScriptCore::JSValue::CallWithArguments(uObject*, uArray*)::$_0::operator()(objc_object*, id<UnoArray>) const /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:216
  29 JavaScriptCore  102.22 MB     -[JSValue callWithArguments:]
  11 CoreFoundation   63.99 MB     __invoking___
  10 fuse-swipeorder-sample   63.99 MB     ___ZZN1g4Fuse9Scripting14JavaScriptCore7JSValue26ValueWithCallbackInContextEP9uDelegateP7uObjectENK4$_24clEU13block_pointerFPU19objcproto9UnoObject11objc_objectP11objc_objectPU18objcproto8UnoArray11objc_objectESC__block_invoke /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:572
   9 fuse-swipeorder-sample   63.86 MB     _ZZZZN1g4Fuse9Scripting14JavaScriptCore7JSValue26ValueWithCallbackInContextEP9uDelegateP7uObjectENK4$_24clEU13block_pointerFPU19objcproto9UnoObject11objc_objectP11objc_objectPU18objcproto8UnoArray11objc_objectESC_EUb0_ENKUlvE1_clEv /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:572
   8 fuse-swipeorder-sample   63.86 MB     g::Fuse::Scripting::JavaScriptCore::Marshaller::Wrap(uObject*) /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.g.cpp:616
   7 fuse-swipeorder-sample   63.84 MB     g::Fuse::Scripting::JavaScriptCore::JSValue::IsExternal(uObject*) /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:320
   6 fuse-swipeorder-sample   63.84 MB     g::Fuse::Scripting::JavaScriptCore::JSValue::IsExternal(uObject*)::$_7::operator()(objc_object*) const /Users/sahalzain/Workspace/Fuse/fuse-swipeorder-sample/build/iOS/Debug/src/Fuse.Scripting.JavaScriptCore.JSValue.mm:322
   5 JavaScriptCore   63.84 MB     -[JSValue toObject]
   0 libsystem_malloc.dylib   33.44 MB     malloc_zone_calloc

I hope the data would useful

Hi!

Thanks for reporting, we will add this info to the issue.

I’ve profiled the code in question and found a fix that should make this significantly faster. The fix needs to go through QA before we ship it, but it’s on the way. Sorry for the inconvenience.

Hi,

That’s a great news, and I assume the fix will be included in the upcoming 0.20 relase? Thanks

Unforunately, I don’t think this will make it in time for for 0.20.0.

We reconsidered, and decided the fix would be included in 0.20.