Skip to content

Commit f633588

Browse files
authored
Merge pull request #61 from Akeit0/optimize-coroutine
Optimize: Reduce unnecessary coping in coroutine
2 parents b9bdda8 + ac731d8 commit f633588

File tree

2 files changed

+16
-24
lines changed

2 files changed

+16
-24
lines changed

sandbox/Benchmark/CoroutineBenchmark.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public void GlobalSetup()
1414
{
1515
core.Setup("coroutine.lua");
1616
core.LuaCSharpState.OpenBasicLibrary();
17+
core.LuaCSharpState.OpenCoroutineLibrary();
1718
}
1819

1920
[Benchmark(Description = "MoonSharp (RunString)")]

src/Lua/LuaCoroutine.cs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
6060
if (isFirstCall)
6161
{
6262
// copy stack value
63-
Stack.EnsureCapacity(baseThread.Stack.Count);
64-
baseThread.Stack.AsSpan().CopyTo(Stack.GetBuffer());
65-
Stack.NotifyTop(baseThread.Stack.Count);
63+
var argCount = context.ArgumentCount;
64+
Stack.EnsureCapacity(argCount);
65+
baseThread.Stack.AsSpan()[^argCount..].CopyTo(Stack.GetBuffer());
66+
Stack.NotifyTop(argCount);
6667
}
6768
else
6869
{
@@ -122,27 +123,19 @@ public override async ValueTask<int> ResumeAsync(LuaFunctionExecutionContext con
122123
if (variableArgumentCount > 0)
123124
{
124125
var fixedArgumentCount = context.ArgumentCount - 1 - variableArgumentCount;
126+
var args = context.Arguments;
125127

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

131130
frameBase = Stack.Count;
132131

133-
for (int i = 0; i < fixedArgumentCount; i++)
134-
{
135-
Stack.Push(context.GetArgument(i + 1));
136-
}
132+
Stack.PushRange(args.Slice(1, fixedArgumentCount));
137133
}
138134
else
139135
{
140136
frameBase = Stack.Count;
141137

142-
for (int i = 0; i < context.ArgumentCount - 1; i++)
143-
{
144-
Stack.Push(context.GetArgument(i + 1));
145-
}
138+
Stack.PushRange(context.Arguments[1..]);
146139
}
147140

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

159-
(var index, var result0, var result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!);
152+
var (index, result0, result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!);
160153

154+
var bufferSpan = buffer.Span;
161155
if (index == 0)
162156
{
163157
var results = result0.Results;
164158

165-
buffer.Span[0] = true;
166-
for (int i = 0; i < results.Length; i++)
167-
{
168-
buffer.Span[i + 1] = results[i];
169-
}
159+
bufferSpan[0] = true;
160+
results.CopyTo(bufferSpan[1..]);
170161

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

177168
Volatile.Write(ref status, (byte)LuaThreadStatus.Dead);
178-
buffer.Span[0] = true;
179-
this.buffer[0..resultCount].CopyTo(buffer.Span[1..]);
169+
bufferSpan[0] = true;
170+
this.buffer.AsSpan()[..resultCount].CopyTo(bufferSpan[1..]);
180171

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

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

192183
Volatile.Write(ref status, (byte)LuaThreadStatus.Dead);
193184
buffer.Span[0] = false;
194-
buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value: ex.Message;
185+
buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value : ex.Message;
195186
return 2;
196187
}
197188
else

0 commit comments

Comments
 (0)