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
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 braces = 0;
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++)
sb.Append(GenerateCSharpDefaultValueNativeToManaged(buildData, items[i], caller, itemType, attribute)).Append(',');
sb.Append('}');
return sb.ToString();
var result = sb.ToString();
PutStringBuilder(sb);
return result;
}
// Special case for value constructors
@@ -1979,7 +1981,7 @@ namespace Flax.Build.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);
// Header
@@ -2019,7 +2021,7 @@ namespace Flax.Build.Bindings
return;
{
var header = new StringBuilder();
var header = GetStringBuilder();
// Using declarations
CSharpUsedNamespacesSorted.Clear();
@@ -2029,12 +2031,14 @@ namespace Flax.Build.Bindings
header.AppendLine($"using {CSharpUsedNamespacesSorted[i]};");
contents.Insert(headerPos, header.ToString());
PutStringBuilder(header);
}
// Save generated file
contents.AppendLine();
contents.AppendLine("#endif");
Utilities.WriteFileIfChanged(bindings.GeneratedCSharpFilePath, contents.ToString());
PutStringBuilder(contents);
}
internal struct GuidInterop
@@ -2051,7 +2055,7 @@ namespace Flax.Build.Bindings
if (binaryModule.All(x => !x.BuildCSharp))
return;
var contents = new StringBuilder();
var contents = GetStringBuilder();
var binaryModuleName = binaryModule.Key;
var project = Builder.GetModuleProject(binaryModule.First(), buildData);
@@ -2089,6 +2093,7 @@ namespace Flax.Build.Bindings
contents.AppendLine("[assembly: DisableRuntimeMarshalling]");
#endif
Utilities.WriteFileIfChanged(dstFilePath, contents.ToString());
PutStringBuilder(contents);
}
}
}

View File

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

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Flax.Build.NativeCpp;
@@ -59,6 +60,26 @@ namespace Flax.Build.Bindings
public static event ParseFunctionParameterTagDelegate ParseFunctionParameterTag;
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)
{
if (buildData.ModulesInfo.TryGetValue(module, out var moduleInfo))