Skip to content

Commit

Permalink
Merge pull request #61 from Akeit0/optimize-coroutine
Browse files Browse the repository at this point in the history
Optimize: Reduce unnecessary coping in coroutine
  • Loading branch information
yn01-dev authored Jan 2, 2025
2 parents b9bdda8 + ac731d8 commit f633588
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 24 deletions.
1 change: 1 addition & 0 deletions sandbox/Benchmark/CoroutineBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public void GlobalSetup()
{
core.Setup("coroutine.lua");
core.LuaCSharpState.OpenBasicLibrary();
core.LuaCSharpState.OpenCoroutineLibrary();
}

[Benchmark(Description = "MoonSharp (RunString)")]
Expand Down
39 changes: 15 additions & 24 deletions src/Lua/LuaCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
if (isFirstCall)
{
// copy stack value
Stack.EnsureCapacity(baseThread.Stack.Count);
baseThread.Stack.AsSpan().CopyTo(Stack.GetBuffer());
Stack.NotifyTop(baseThread.Stack.Count);
var argCount = context.ArgumentCount;
Stack.EnsureCapacity(argCount);
baseThread.Stack.AsSpan()[^argCount..].CopyTo(Stack.GetBuffer());
Stack.NotifyTop(argCount);
}
else
{
Expand Down Expand Up @@ -122,27 +123,19 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
if (variableArgumentCount > 0)
{
var fixedArgumentCount = context.ArgumentCount - 1 - variableArgumentCount;
var args = context.Arguments;

for (int i = 0; i < variableArgumentCount; i++)
{
Stack.Push(context.GetArgument(i + fixedArgumentCount + 1));
}
Stack.PushRange(args.Slice(1 + fixedArgumentCount, variableArgumentCount));

frameBase = Stack.Count;

for (int i = 0; i < fixedArgumentCount; i++)
{
Stack.Push(context.GetArgument(i + 1));
}
Stack.PushRange(args.Slice(1, fixedArgumentCount));
}
else
{
frameBase = Stack.Count;

for (int i = 0; i < context.ArgumentCount - 1; i++)
{
Stack.Push(context.GetArgument(i + 1));
}
Stack.PushRange(context.Arguments[1..]);
}

functionTask = Function.InvokeAsync(new()
Expand All @@ -156,17 +149,15 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
Volatile.Write(ref isFirstCall, false);
}

(var index, var result0, var result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!);
var (index, result0, result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!);

var bufferSpan = buffer.Span;
if (index == 0)
{
var results = result0.Results;

buffer.Span[0] = true;
for (int i = 0; i < results.Length; i++)
{
buffer.Span[i + 1] = results[i];
}
bufferSpan[0] = true;
results.CopyTo(bufferSpan[1..]);

return results.Length + 1;
}
Expand All @@ -175,8 +166,8 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
var resultCount = functionTask!.Result;

Volatile.Write(ref status, (byte)LuaThreadStatus.Dead);
buffer.Span[0] = true;
this.buffer[0..resultCount].CopyTo(buffer.Span[1..]);
bufferSpan[0] = true;
this.buffer.AsSpan()[..resultCount].CopyTo(bufferSpan[1..]);

ArrayPool<LuaValue>.Shared.Return(this.buffer);

Expand All @@ -191,7 +182,7 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con

Volatile.Write(ref status, (byte)LuaThreadStatus.Dead);
buffer.Span[0] = false;
buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value: ex.Message;
buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value : ex.Message;
return 2;
}
else
Expand Down

0 comments on commit f633588

Please sign in to comment.