Optimize bindings code generation via String Builder pooling

This commit is contained in:
Wojciech Figat
2023-01-23 13:22:43 +01:00
parent a633aa69c3
commit 25811ed6d4
3 changed files with 42 additions and 10 deletions

View File

@@ -208,7 +208,7 @@ namespace Flax.Build.Bindings
} }
else else
throw new Exception("Cannot use array initializer as default value for type " + valueType); throw new Exception("Cannot use array initializer as default value for type " + valueType);
var sb = new StringBuilder(); var sb = GetStringBuilder();
var items = new List<string>(); var items = new List<string>();
var braces = 0; var braces = 0;
for (int i = 1; i < value.Length - 1; i++) for (int i = 1; i < value.Length - 1; i++)
@@ -232,7 +232,9 @@ namespace Flax.Build.Bindings
for (int i = 0; i < items.Count; i++) for (int i = 0; i < items.Count; i++)
sb.Append(GenerateCSharpDefaultValueNativeToManaged(buildData, items[i], caller, itemType, attribute)).Append(','); sb.Append(GenerateCSharpDefaultValueNativeToManaged(buildData, items[i], caller, itemType, attribute)).Append(',');
sb.Append('}'); sb.Append('}');
return sb.ToString(); var result = sb.ToString();
PutStringBuilder(sb);
return result;
} }
// Special case for value constructors // Special case for value constructors
@@ -1979,7 +1981,7 @@ namespace Flax.Build.Bindings
private static void GenerateCSharp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings) private static void GenerateCSharp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings)
{ {
var contents = new StringBuilder(); var contents = GetStringBuilder();
buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo); buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo);
// Header // Header
@@ -2019,7 +2021,7 @@ namespace Flax.Build.Bindings
return; return;
{ {
var header = new StringBuilder(); var header = GetStringBuilder();
// Using declarations // Using declarations
CSharpUsedNamespacesSorted.Clear(); CSharpUsedNamespacesSorted.Clear();
@@ -2029,12 +2031,14 @@ namespace Flax.Build.Bindings
header.AppendLine($"using {CSharpUsedNamespacesSorted[i]};"); header.AppendLine($"using {CSharpUsedNamespacesSorted[i]};");
contents.Insert(headerPos, header.ToString()); contents.Insert(headerPos, header.ToString());
PutStringBuilder(header);
} }
// Save generated file // Save generated file
contents.AppendLine(); contents.AppendLine();
contents.AppendLine("#endif"); contents.AppendLine("#endif");
Utilities.WriteFileIfChanged(bindings.GeneratedCSharpFilePath, contents.ToString()); Utilities.WriteFileIfChanged(bindings.GeneratedCSharpFilePath, contents.ToString());
PutStringBuilder(contents);
} }
internal struct GuidInterop internal struct GuidInterop
@@ -2051,7 +2055,7 @@ namespace Flax.Build.Bindings
if (binaryModule.All(x => !x.BuildCSharp)) if (binaryModule.All(x => !x.BuildCSharp))
return; return;
var contents = new StringBuilder(); var contents = GetStringBuilder();
var binaryModuleName = binaryModule.Key; var binaryModuleName = binaryModule.Key;
var project = Builder.GetModuleProject(binaryModule.First(), buildData); var project = Builder.GetModuleProject(binaryModule.First(), buildData);
@@ -2089,6 +2093,7 @@ namespace Flax.Build.Bindings
contents.AppendLine("[assembly: DisableRuntimeMarshalling]"); contents.AppendLine("[assembly: DisableRuntimeMarshalling]");
#endif #endif
Utilities.WriteFileIfChanged(dstFilePath, contents.ToString()); Utilities.WriteFileIfChanged(dstFilePath, contents.ToString());
PutStringBuilder(contents);
} }
} }
} }

View File

@@ -83,7 +83,7 @@ namespace Flax.Build.Bindings
private static string GenerateCppWrapperNativeToVariantMethodName(TypeInfo typeInfo) private static string GenerateCppWrapperNativeToVariantMethodName(TypeInfo typeInfo)
{ {
var sb = new StringBuilder(); var sb = GetStringBuilder();
sb.Append(typeInfo.Type.Replace("::", "_")); sb.Append(typeInfo.Type.Replace("::", "_"));
if (typeInfo.IsPtr) if (typeInfo.IsPtr)
sb.Append("Ptr"); sb.Append("Ptr");
@@ -96,7 +96,9 @@ namespace Flax.Build.Bindings
sb.Append("Ptr"); sb.Append("Ptr");
} }
} }
return sb.ToString(); var result = sb.ToString();
PutStringBuilder(sb);
return result;
} }
private static string GenerateCppWrapperNativeToManagedParam(BuildData buildData, StringBuilder contents, TypeInfo paramType, string paramName, ApiTypeInfo caller, bool isRef, out bool useLocalVar) private static string GenerateCppWrapperNativeToManagedParam(BuildData buildData, StringBuilder contents, TypeInfo paramType, string paramName, ApiTypeInfo caller, bool isRef, out bool useLocalVar)
@@ -2548,7 +2550,7 @@ namespace Flax.Build.Bindings
private static void GenerateCpp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings) private static void GenerateCpp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings)
{ {
var contents = new StringBuilder(); var contents = GetStringBuilder();
CppUsedNonPodTypes.Clear(); CppUsedNonPodTypes.Clear();
CppReferencesFiles.Clear(); CppReferencesFiles.Clear();
CppIncludeFiles.Clear(); CppIncludeFiles.Clear();
@@ -2591,7 +2593,7 @@ namespace Flax.Build.Bindings
GenerateCppModuleSource?.Invoke(buildData, moduleInfo, contents); GenerateCppModuleSource?.Invoke(buildData, moduleInfo, contents);
{ {
var header = new StringBuilder(); var header = GetStringBuilder();
// Variant converting helper methods // Variant converting helper methods
foreach (var typeInfo in CppVariantToTypes) foreach (var typeInfo in CppVariantToTypes)
@@ -2675,6 +2677,8 @@ namespace Flax.Build.Bindings
header.Append(" return result;").AppendLine(); header.Append(" return result;").AppendLine();
header.Append('}').AppendLine(); header.Append('}').AppendLine();
header.AppendLine("}"); header.AppendLine("}");
PutStringBuilder(header);
} }
// Non-POD types // Non-POD types
@@ -2969,6 +2973,7 @@ namespace Flax.Build.Bindings
contents.AppendLine("PRAGMA_ENABLE_DEPRECATION_WARNINGS"); contents.AppendLine("PRAGMA_ENABLE_DEPRECATION_WARNINGS");
Utilities.WriteFileIfChanged(bindings.GeneratedCppFilePath, contents.ToString()); Utilities.WriteFileIfChanged(bindings.GeneratedCppFilePath, contents.ToString());
PutStringBuilder(contents);
} }
private static void GenerateCpp(BuildData buildData, IGrouping<string, Module> binaryModule) private static void GenerateCpp(BuildData buildData, IGrouping<string, Module> binaryModule)
@@ -2978,7 +2983,7 @@ namespace Flax.Build.Bindings
return; return;
var useCSharp = binaryModule.Any(x => x.BuildCSharp); var useCSharp = binaryModule.Any(x => x.BuildCSharp);
var contents = new StringBuilder(); var contents = GetStringBuilder();
var binaryModuleName = binaryModule.Key; var binaryModuleName = binaryModule.Key;
var binaryModuleNameUpper = binaryModuleName.ToUpperInvariant(); var binaryModuleNameUpper = binaryModuleName.ToUpperInvariant();
var project = Builder.GetModuleProject(binaryModule.First(), buildData); var project = Builder.GetModuleProject(binaryModule.First(), buildData);
@@ -3031,6 +3036,7 @@ namespace Flax.Build.Bindings
contents.AppendLine("}"); contents.AppendLine("}");
GenerateCppBinaryModuleSource?.Invoke(buildData, binaryModule, contents); GenerateCppBinaryModuleSource?.Invoke(buildData, binaryModule, contents);
Utilities.WriteFileIfChanged(binaryModuleSourcePath, contents.ToString()); Utilities.WriteFileIfChanged(binaryModuleSourcePath, contents.ToString());
PutStringBuilder(contents);
} }
} }
} }

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flax.Build.NativeCpp; using Flax.Build.NativeCpp;
@@ -59,6 +60,26 @@ namespace Flax.Build.Bindings
public static event ParseFunctionParameterTagDelegate ParseFunctionParameterTag; public static event ParseFunctionParameterTagDelegate ParseFunctionParameterTag;
public static ModuleInfo CurrentModule; public static ModuleInfo CurrentModule;
private static List<StringBuilder> _strignBuilderCache;
private static StringBuilder GetStringBuilder()
{
if (_strignBuilderCache == null || _strignBuilderCache.Count == 0)
return new StringBuilder();
var idx = _strignBuilderCache.Count - 1;
var result = _strignBuilderCache[idx];
_strignBuilderCache.RemoveAt(idx);
result.Clear();
return result;
}
private static void PutStringBuilder(StringBuilder value)
{
if (_strignBuilderCache == null)
_strignBuilderCache = new List<StringBuilder>();
_strignBuilderCache.Add(value);
}
public static ModuleInfo ParseModule(BuildData buildData, Module module, BuildOptions moduleOptions = null) public static ModuleInfo ParseModule(BuildData buildData, Module module, BuildOptions moduleOptions = null)
{ {
if (buildData.ModulesInfo.TryGetValue(module, out var moduleInfo)) if (buildData.ModulesInfo.TryGetValue(module, out var moduleInfo))