I make test for internal call pass difference args:
The cost with call 100000 times result is:
pass (str, int, float): 1020ms
pass(int, float): 900ms
pass(int, int): 200ms
``` C#
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void TestPassValueWithStrIntFloat(string a, int b, float c);
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void TestPassValueWithIntFloat(int b, float c);
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void TestPassValueWithIntInt(int b, int c);
saw = Stopwatch.StartNew();
sw.Start();
string str = "111";
for(int i = 0;i < 999999; i++)
{
TestPassValueWithStrIntFloat(str, 1, 1.0f);
}
sw.Stop();
Console.WriteLine(String.Format("test_c_func_set_value_with_str_int_float, Time taken: {0}ms", sw.Elapsed.TotalMilliseconds));
sw = Stopwatch.StartNew();
sw.Start();
for(int i = 0;i < 999999; i++)
TestPassValueWithIntFloat(1, 1.0f);
sw.Stop();
Console.WriteLine(String.Format("test_c_func_set_value_with_int_float, Time taken: {0}ms", sw.Elapsed.TotalMilliseconds));
sw = Stopwatch.StartNew();
sw.Start();
for(int i = 0;i < 999999; i++)
TestPassValueWithIntInt(1, 1);
sw.Stop();
Console.WriteLine(String.Format("test_c_func_set_value_with_int_int, Time taken: {0}ms", sw.Elapsed.TotalMilliseconds));
## The C side code:
``` c
void TestPassValueWithStrIntFloat(MonoString* text, int a, float b)
{
}
void TestPassValueWithIntFloat(int a, float b)
{
}
void TestPassValueWithIntInt(int a, int b)
{
}
// add internal_call
mono_add_internal_call("TestRunner::TestPassValueWithStrIntFloat", TestPassValueWithStrIntFloat);
mono_add_internal_call("TestRunner::TestPassValueWithIntFloat", TestPassValueWithIntFloat);
mono_add_internal_call("TestRunner::TestPassValueWithIntInt", TestPassValueWithIntInt);
And the mono init setup mode:
void mono_ios_setup_execution_mode (void)
{
mono_icall_table_init ();
mono_marshal_ilgen_init ();
mono_method_builder_ilgen_init ();
mono_sgen_mono_ilgen_init ();
mono_ee_interp_init (0);
mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP);
}
2019-01-18 12:04:22.954022+0800 RunMonoOniOS[78000:6466784] [stdout] test_c_func_set_value_with_str_int_float, Time taken: 1020.8563ms
2019-01-18 12:04:23.869507+0800 RunMonoOniOS[78000:6466784] [stdout] test_c_func_set_value_with_int_float, Time taken: 915.0514ms
2019-01-18 12:04:24.073775+0800 RunMonoOniOS[78000:6466784] [stdout] test_c_func_set_value_with_int_int, Time taken: 203.8157ms
@migueldeicaza can you help me?
why and how can I make the optimization?
thank you !
@srxqds I am assuming the main slowness comes from passing the floating argument. On the interpreter we only optimise native calls that use the general registers. If you are passing a float argument we fallback to a slower, general path. You could avoid this by passing the floating value by reference, or somehow pass it by value but as an integer.
Passing managed objects can also produce additional overhead.
Most helpful comment
@srxqds I am assuming the main slowness comes from passing the floating argument. On the interpreter we only optimise native calls that use the general registers. If you are passing a float argument we fallback to a slower, general path. You could avoid this by passing the floating value by reference, or somehow pass it by value but as an integer.
Passing managed objects can also produce additional overhead.