Skip to content

Commit

Permalink
kmgen: [dotnet] small performance improvement
Browse files Browse the repository at this point in the history
This change adds some performance improvement for array/slice.
  • Loading branch information
inkeliz committed Sep 17, 2022
1 parent b08ab05 commit b3815fe
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 38 deletions.
67 changes: 39 additions & 28 deletions benchmark/km/game_generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ public enum Team : byte {
Aliens = 4,
}

internal static unsafe class _GlobalsReflect
{
public static System.Reflection.FieldInfo _Size_12254962724431809041_29 = typeof(List<byte>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_12254962724431809041_29 = typeof(List<byte>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Size_12254962724431809041_38 = typeof(List<double>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_12254962724431809041_38 = typeof(List<double>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Size_12254962724431809041_78 = typeof(List<int>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_12254962724431809041_78 = typeof(List<int>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Size_12254962724431809041_86 = typeof(List<Weapon>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_12254962724431809041_86 = typeof(List<Weapon>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Size_12254962724431809041_102 = typeof(List<Vec3>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_12254962724431809041_102 = typeof(List<Vec3>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Size_14096677544474027661_4 = typeof(List<Monster>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_14096677544474027661_4 = typeof(List<Monster>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
}

public enum PacketIdentifier : ulong {
Vec3 = 10268726485798425099,
WeaponData = 15342010214468761012,
Expand Down Expand Up @@ -316,13 +332,11 @@ public unsafe struct MonsterData {
var __ColorOffset = offset+37;
writer.WriteAt(__ColorOffset, (long)this._Color);
var __HitboxOffset = offset+38;
for (var i = 0; i < 5; i++) {
if (i < this._Hitbox.Count) {
writer.WriteAt(__HitboxOffset, this._Hitbox[i]);
} else {
writer.WriteAt(__HitboxOffset, 0);
if (this._Hitbox.Count > 0) {
var array = (double[])_GlobalsReflect._Items_12254962724431809041_38.GetValue(this._Hitbox);
fixed (void* first = &array[0]) {
Buffer.MemoryCopy(first, (writer.Memory + new IntPtr(__HitboxOffset)).ToPointer(), this._Hitbox.Count * 8, this._Hitbox.Count * 8);
}
__HitboxOffset += 8;
}
var __StatusSize = (uint)(4 * this._Status.Count);
var __StatusOffset = writer.Alloc(__StatusSize);
Expand Down Expand Up @@ -382,11 +396,10 @@ public unsafe struct MonsterData {
this._Inventory.Add(0);
}
}
this._Inventory.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Inventory, __InventoryLen);
}
for (var i = 0; i < __InventoryLen; i++) {
this._Inventory[i] = __InventorySlice[i];
_GlobalsReflect._Size_12254962724431809041_29.SetValue(this._Inventory, __InventoryLen);
}
var __InventorySpan = CollectionsMarshal.AsSpan(this._Inventory);
__InventorySlice.TryCopyTo(__InventorySpan);
this._Color = (Color)(viewer.Color());
var __HitboxSlice = viewer.Hitbox();
var __HitboxLen = __HitboxSlice.Length;
Expand All @@ -400,11 +413,10 @@ public unsafe struct MonsterData {
this._Hitbox.Add(0);
}
}
this._Hitbox.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Hitbox, __HitboxLen);
}
for (var i = 0; i < __HitboxLen; i++) {
this._Hitbox[i] = __HitboxSlice[i];
_GlobalsReflect._Size_12254962724431809041_38.SetValue(this._Hitbox, __HitboxLen);
}
var __HitboxSpan = CollectionsMarshal.AsSpan(this._Hitbox);
__HitboxSlice.TryCopyTo(__HitboxSpan);
for (var i = __HitboxLen; i < this._Hitbox.Count; i++) {
this._Hitbox[i] = 0;
}
Expand All @@ -417,11 +429,10 @@ public unsafe struct MonsterData {
this._Status.Add(0);
}
}
this._Status.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Status, __StatusLen);
}
for (var i = 0; i < __StatusLen; i++) {
this._Status[i] = __StatusSlice[i];
_GlobalsReflect._Size_12254962724431809041_78.SetValue(this._Status, __StatusLen);
}
var __StatusSpan = CollectionsMarshal.AsSpan(this._Status);
__StatusSlice.TryCopyTo(__StatusSpan);
var __WeaponsSlice = viewer.Weapons();
var __WeaponsLen = __WeaponsSlice.Length;
if (__WeaponsLen > 4) {
Expand All @@ -434,7 +445,7 @@ public unsafe struct MonsterData {
this._Weapons.Add(new Weapon());
}
}
this._Weapons.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Weapons, __WeaponsLen);
_GlobalsReflect._Size_12254962724431809041_86.SetValue(this._Weapons, __WeaponsLen);
}
var __WeaponsSpan = CollectionsMarshal.AsSpan(this._Weapons);
for (var i = 0; i < __WeaponsLen; i++) {
Expand All @@ -454,7 +465,7 @@ public unsafe struct MonsterData {
this._Path.Add(new Vec3());
}
}
this._Path.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Path, __PathLen);
_GlobalsReflect._Size_12254962724431809041_102.SetValue(this._Path, __PathLen);
}
var __PathSpan = CollectionsMarshal.AsSpan(this._Path);
for (var i = 0; i < __PathLen; i++) {
Expand Down Expand Up @@ -591,7 +602,7 @@ public unsafe struct Monsters {
this._Monsters.Add(new Monster());
}
}
this._Monsters.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._Monsters, __MonstersLen);
_GlobalsReflect._Size_14096677544474027661_4.SetValue(this._Monsters, __MonstersLen);
}
var __MonstersSpan = CollectionsMarshal.AsSpan(this._Monsters);
for (var i = 0; i < __MonstersLen; i++) {
Expand All @@ -611,7 +622,7 @@ public unsafe struct Vec3Viewer {
if (!reader.IsValidOffset(offset, 12)) {
return ref *(Vec3Viewer*)(nuint)_Globals.Null();
}
ref Vec3Viewer v = ref *(Vec3Viewer*)(reader.MemoryPointer + offset);
ref Vec3Viewer v = ref Unsafe.AsRef<Vec3Viewer>((void*)(reader.MemoryPointer + offset));
return ref v;
}

Expand Down Expand Up @@ -645,7 +656,7 @@ public unsafe struct WeaponDataViewer {
if (!reader.IsValidOffset(offset, 4)) {
return ref *(WeaponDataViewer*)(nuint)_Globals.Null();
}
ref WeaponDataViewer v = ref *(WeaponDataViewer*)(reader.MemoryPointer + offset);
ref WeaponDataViewer v = ref Unsafe.AsRef<WeaponDataViewer>((void*)(reader.MemoryPointer + offset));
if (!reader.IsValidOffset(offset, v.KarmemSizeOf())) {
return ref *(WeaponDataViewer*)(nuint)_Globals.Null();
}
Expand Down Expand Up @@ -702,7 +713,7 @@ public unsafe struct WeaponViewer {
if (!reader.IsValidOffset(offset, 4)) {
return ref *(WeaponViewer*)(nuint)_Globals.Null();
}
ref WeaponViewer v = ref *(WeaponViewer*)(reader.MemoryPointer + offset);
ref WeaponViewer v = ref Unsafe.AsRef<WeaponViewer>((void*)(reader.MemoryPointer + offset));
return ref v;
}

Expand Down Expand Up @@ -741,7 +752,7 @@ public unsafe struct MonsterDataViewer {
if (!reader.IsValidOffset(offset, 4)) {
return ref *(MonsterDataViewer*)(nuint)_Globals.Null();
}
ref MonsterDataViewer v = ref *(MonsterDataViewer*)(reader.MemoryPointer + offset);
ref MonsterDataViewer v = ref Unsafe.AsRef<MonsterDataViewer>((void*)(reader.MemoryPointer + offset));
if (!reader.IsValidOffset(offset, v.KarmemSizeOf())) {
return ref *(MonsterDataViewer*)(nuint)_Globals.Null();
}
Expand All @@ -757,7 +768,7 @@ public unsafe struct MonsterDataViewer {
if (4 + 12 > this.KarmemSizeOf()) {
return ref *(Vec3Viewer*)((nuint)_Globals.Null());
}
return ref *(Vec3Viewer*)((nuint)Unsafe.AsPointer(ref this) + 4);
return ref Unsafe.AsRef<Vec3Viewer>((void*)((nuint)Unsafe.AsPointer(ref this) + 4));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short Mana() {
Expand Down Expand Up @@ -883,7 +894,7 @@ public unsafe struct MonsterViewer {
if (!reader.IsValidOffset(offset, 4)) {
return ref *(MonsterViewer*)(nuint)_Globals.Null();
}
ref MonsterViewer v = ref *(MonsterViewer*)(reader.MemoryPointer + offset);
ref MonsterViewer v = ref Unsafe.AsRef<MonsterViewer>((void*)(reader.MemoryPointer + offset));
return ref v;
}

Expand All @@ -908,7 +919,7 @@ public unsafe struct MonstersViewer {
if (!reader.IsValidOffset(offset, 4)) {
return ref *(MonstersViewer*)(nuint)_Globals.Null();
}
ref MonstersViewer v = ref *(MonstersViewer*)(reader.MemoryPointer + offset);
ref MonstersViewer v = ref Unsafe.AsRef<MonstersViewer>((void*)(reader.MemoryPointer + offset));
if (!reader.IsValidOffset(offset, v.KarmemSizeOf())) {
return ref *(MonstersViewer*)(nuint)_Globals.Null();
}
Expand Down
31 changes: 21 additions & 10 deletions cmd/karmem/kmgen/dotnet_template.dotnettmpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ public enum {{$root.Data.Name}} : {{ToType $root.Data.Type}} {
{{define "struct"}}
{{- /*gotype: karmem.org/cmd/karmem/kmparser.File*/ -}}

internal static unsafe class _GlobalsReflect
{
{{- range $root := .Structs }}
{{- range $field := $root.Data.Fields }}
{{- if or $field.Data.Type.IsSlice $field.Data.Type.IsArray }}
{{- if not $field.Data.Type.IsString }}
public static System.Reflection.FieldInfo _Size_{{$root.Data.ID}}_{{$field.Data.Offset}} = typeof({{ToType $field.Data.Type}}).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
public static System.Reflection.FieldInfo _Items_{{$root.Data.ID}}_{{$field.Data.Offset}} = typeof({{ToType $field.Data.Type}}).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
{{- end }}
{{- end }}
{{- end }}
{{- end }}
}

public enum PacketIdentifier : ulong {
{{- range $root := .Structs}}
{{$root.Data.Name}} = {{$root.Data.ID}},
Expand Down Expand Up @@ -129,13 +143,11 @@ public unsafe struct {{$root.Data.Name}} {
{{- if or $field.Data.Type.IsNative $field.Data.Type.IsEnum }}
{{- if $field.Data.Type.IsInline}}
{{- if $field.Data.Type.IsArray }}
for (var i = 0; i < {{$field.Data.Type.Length}}; i++) {
if (i < this._{{$field.Data.Name}}.Count) {
writer.WriteAt(__{{$field.Data.Name}}Offset, this._{{$field.Data.Name}}[i]);
} else {
writer.WriteAt(__{{$field.Data.Name}}Offset, {{ToPlainDefault $field.Data.Type}});
if (this._{{$field.Data.Name}}.Count > 0) {
var array = ({{ToPlainType $field.Data.Type}}[])_GlobalsReflect._Items_{{$root.Data.ID}}_{{$field.Data.Offset}}.GetValue(this._{{$field.Data.Name}});
fixed (void* first = &array[0]) {
Buffer.MemoryCopy(first, (writer.Memory + new IntPtr(__{{$field.Data.Name}}Offset)).ToPointer(), this._{{$field.Data.Name}}.Count * {{$field.Data.Size.Allocation}}, this._{{$field.Data.Name}}.Count * {{$field.Data.Size.Allocation}});
}
__{{$field.Data.Name}}Offset += {{$field.Data.Size.Allocation}};
}
{{- else }}
{{- if $field.Data.Type.IsEnum }}
Expand Down Expand Up @@ -217,12 +229,11 @@ public unsafe struct {{$root.Data.Name}} {
this._{{$field.Data.Name}}.Add({{ToPlainDefault $field.Data.Type}});
}
}
this._{{$field.Data.Name}}.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).SetValue(this._{{$field.Data.Name}}, __{{$field.Data.Name}}Len);
_GlobalsReflect._Size_{{$root.Data.ID}}_{{$field.Data.Offset}}.SetValue(this._{{$field.Data.Name}}, __{{$field.Data.Name}}Len);
}
{{- if $field.Data.Type.IsNative}}
for (var i = 0; i < __{{$field.Data.Name}}Len; i++) {
this._{{$field.Data.Name}}[i] = __{{$field.Data.Name}}Slice[i];
}
var __{{$field.Data.Name}}Span = CollectionsMarshal.AsSpan(this._{{$field.Data.Name}});
__{{$field.Data.Name}}Slice.TryCopyTo(__{{$field.Data.Name}}Span);
{{- if $field.Data.Type.IsArray }}
for (var i = __{{$field.Data.Name}}Len; i < this._{{$field.Data.Name}}.Count; i++) {
this._{{$field.Data.Name}}[i] = {{ToPlainDefault $field.Data.Type}};
Expand Down

0 comments on commit b3815fe

Please sign in to comment.