add a benchmark proj
This commit is contained in:
@@ -1,61 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
|
||||||
|
|
||||||
project(StgSharpDevelop C)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Compiler and environment checks
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# Detect compiler family and allow only GCC or Clang when using CMake.
|
|
||||||
if(MSVC)
|
|
||||||
message(FATAL_ERROR "MSVC detected while configuring with CMake. This repository provides .vcxproj files for MSVC/Visual Studio.\nPlease open the solution in Visual Studio or use the existing .vcxproj files to build with MSVC. CMake-based MSVC builds are not supported by this project.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
|
||||||
message(STATUS "Using GCC: ${CMAKE_C_COMPILER}")
|
|
||||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
|
||||||
message(STATUS "Using Clang: ${CMAKE_C_COMPILER}")
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported compiler '${CMAKE_C_COMPILER_ID}'. Supported compilers for CMake builds are: GCC and Clang. MSVC users: use the provided .vcxproj and Visual Studio.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Global configuration types
|
|
||||||
################################################################################
|
|
||||||
set(CMAKE_CONFIGURATION_TYPES
|
|
||||||
"Debug"
|
|
||||||
"Release"
|
|
||||||
CACHE STRING "" FORCE
|
|
||||||
)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Nuget packages function stub.
|
|
||||||
################################################################################
|
|
||||||
function(use_package TARGET PACKAGE VERSION)
|
|
||||||
message(WARNING "No implementation of use_package. Create yours. "
|
|
||||||
"Package \"${PACKAGE}\" with version \"${VERSION}\" "
|
|
||||||
"for target \"${TARGET}\" is ignored!")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Common utils
|
|
||||||
################################################################################
|
|
||||||
include(CMake/Utils.cmake)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Additional Global Settings(add specific info there)
|
|
||||||
################################################################################
|
|
||||||
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Use solution folders feature
|
|
||||||
################################################################################
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Sub-projects
|
|
||||||
################################################################################
|
|
||||||
add_subdirectory(StgSharp.Native)
|
|
||||||
|
|
||||||
@@ -62,6 +62,16 @@ Terminal-based user interface:
|
|||||||
- **Memory Management**: Custom allocators including HLSF (Hybrid Layer Segregated Fit)
|
- **Memory Management**: Custom allocators including HLSF (Hybrid Layer Segregated Fit)
|
||||||
- **Thread Pool Management**: Efficient task scheduling and execution
|
- **Thread Pool Management**: Efficient task scheduling and execution
|
||||||
|
|
||||||
|
#### HLSF Benchmark Snapshot (BenchmarkDotNet)
|
||||||
|
Environment: Windows 11 (10.0.26100.7623), AMD Ryzen 7 6800H, .NET 8.0.23, x64 RyuJIT AVX2, GC = Concurrent Workstation.
|
||||||
|
|
||||||
|
| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
|
||||||
|
|------- |-----:|-----:|------:|------:|-------:|----------:|-----------:|
|
||||||
|
| Hlsf | 838.4 µs | 16.67 µs | 40.58 µs | 1.00 | 0.12 | 64 B | 1.00 |
|
||||||
|
| Libc | 849.8 µs | 34.93 µs | 100.23 µs | 1.01 | 0.17 | 64 B | 1.00 |
|
||||||
|
|
||||||
|
This shows HLSF matching libc allocation throughput under the same workload. See the HLSF document for details and caveats.
|
||||||
|
|
||||||
### Graphics and Rendering
|
### Graphics and Rendering
|
||||||
- **OpenGL Integration**: Complete OpenGL API coverage
|
- **OpenGL Integration**: Complete OpenGL API coverage
|
||||||
- **Cross-Platform Support**: Windows and Linux compatibility
|
- **Cross-Platform Support**: Windows and Linux compatibility
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="HlsfAllocatorBench"
|
||||||
|
// Project: StgSharp
|
||||||
|
// AuthorGroup: Nitload
|
||||||
|
// Copyright (c) Nitload. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using StgSharp.HighPerformance.Memory;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace StgSharp.Benchmark
|
||||||
|
{
|
||||||
|
[MemoryDiagnoser]
|
||||||
|
[InvocationCount(16)]
|
||||||
|
public class HlsfAllocatorBench
|
||||||
|
{
|
||||||
|
|
||||||
|
private const int AllocationCount = 2048;
|
||||||
|
|
||||||
|
private static readonly int[] AllocSizes = [
|
||||||
|
64,
|
||||||
|
96,
|
||||||
|
150,
|
||||||
|
200,
|
||||||
|
400,
|
||||||
|
1024,
|
||||||
|
4096
|
||||||
|
];
|
||||||
|
private HybridLayerSegregatedFitAllocator _hlsfAllocator = null!;
|
||||||
|
private readonly List<HybridLayerSegregatedFitAllocationHandle> _hlsfLocalList = new();
|
||||||
|
private readonly List<nint> _libcLocalList = new();
|
||||||
|
private Random _random = new(42);
|
||||||
|
|
||||||
|
[GlobalCleanup]
|
||||||
|
public void Cleanup()
|
||||||
|
{
|
||||||
|
_hlsfAllocator.Dispose();
|
||||||
|
_hlsfLocalList.Clear();
|
||||||
|
_hlsfLocalList.TrimExcess();
|
||||||
|
_libcLocalList.Clear();
|
||||||
|
_libcLocalList.TrimExcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void Hlsf()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < AllocationCount; i++)
|
||||||
|
{
|
||||||
|
lock (_hlsfAllocator)
|
||||||
|
{
|
||||||
|
HybridLayerSegregatedFitAllocationHandle allocate = _hlsfAllocator.Alloc(GetNextRandomSize());
|
||||||
|
_hlsfLocalList.Add(allocate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _hlsfLocalList.Count; i++)
|
||||||
|
{
|
||||||
|
lock (_hlsfAllocator) {
|
||||||
|
_hlsfAllocator.Free(_hlsfLocalList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvocationSetup()
|
||||||
|
{
|
||||||
|
_hlsfLocalList.Clear();
|
||||||
|
_libcLocalList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
[IterationSetup]
|
||||||
|
public void IterationSetup()
|
||||||
|
{
|
||||||
|
_hlsfLocalList.Clear();
|
||||||
|
_libcLocalList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark(Baseline = true)]
|
||||||
|
public unsafe void Libc()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < AllocationCount; i++)
|
||||||
|
{
|
||||||
|
void* allocate = NativeMemory.AlignedAlloc(GetNextRandomSize(), 64);
|
||||||
|
_libcLocalList.Add((nint)allocate);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _libcLocalList.Count; i++) {
|
||||||
|
NativeMemory.AlignedFree((void*)_libcLocalList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_random = new Random(42);
|
||||||
|
_hlsfAllocator = new HybridLayerSegregatedFitAllocator(GetArenaBytes(), align:64);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static nuint GetArenaBytes()
|
||||||
|
{
|
||||||
|
const int defaultMb = 512;
|
||||||
|
const int minMb = 64;
|
||||||
|
int mb = defaultMb;
|
||||||
|
|
||||||
|
string? env = Environment.GetEnvironmentVariable("HLSF_BENCH_ARENA_MB");
|
||||||
|
if (!string.IsNullOrWhiteSpace(env) &&
|
||||||
|
int.TryParse(env, out int parsed) &&
|
||||||
|
parsed >= minMb) {
|
||||||
|
mb = parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (nuint)mb * 1024u * 1024u;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint GetNextRandomSize() => (uint)AllocSizes[_random.Next(AllocSizes.Length)];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="Program"
|
||||||
|
// Project: StgSharp
|
||||||
|
// AuthorGroup: Nitload
|
||||||
|
// Copyright (c) Nitload. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
using StgSharp.Benchmark;
|
||||||
|
|
||||||
|
namespace StgSharp.Benchmark
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void Main(
|
||||||
|
string[] args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BenchmarkRunner.Run<HlsfAllocatorBench>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>x64</Platforms>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionDir Condition="'$(SolutionDir)'=='' Or '$(SolutionDir)'=='*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\StgSharp.Common\StgSharp.Common.csproj" Properties="DisablePostBuildCopy=true" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<NativeArtifacts Include="$(SolutionDir)build\**\StgSharp.Native*.dll" />
|
||||||
|
<NativeArtifacts Include="$(SolutionDir)build\**\StgSharp.Native*.pdb" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyNativeArtifacts" AfterTargets="Build" Condition="'$(DisableNativeCopy)'!='true'">
|
||||||
|
<Copy SourceFiles="@(NativeArtifacts)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" Condition="@(NativeArtifacts) != ''" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -75,6 +75,19 @@ Notes:
|
|||||||
- Peak no-touch at 2MB (~17.99M alloc/s). Peak touch near 64B (~17.52M alloc/s).
|
- Peak no-touch at 2MB (~17.99M alloc/s). Peak touch near 64B (~17.52M alloc/s).
|
||||||
- Non-aligned sizes (e.g., 768B, 3KB) typically lower due to slicing/boundary handling.
|
- Non-aligned sizes (e.g., 768B, 3KB) typically lower due to slicing/boundary handling.
|
||||||
|
|
||||||
|
### BenchmarkDotNet (HLSF vs Libc)
|
||||||
|
|
||||||
|
Environment: .NET 8.0.23 (Release), x64 RyuJIT AVX2, Windows 11, AMD Ryzen 7 6800H.
|
||||||
|
|
||||||
|
| Method | Mean | StdDev | Ratio | Allocated |
|
||||||
|
|------- |-----:|------:|------:|----------:|
|
||||||
|
| Hlsf | 838.4 µs | 40.6 µs | 1.00 | 64 B |
|
||||||
|
| Libc | 849.8 µs | 100.2 µs | 1.01 | 64 B |
|
||||||
|
|
||||||
|
Interpretation: HLSF matches libc allocation throughput under the same workload, with slightly tighter dispersion in this run.
|
||||||
|
|
||||||
|
> Note: BenchmarkDotNet also warned that the minimum iteration time was under 1ms; for more stable statistics, increase per-iteration work (e.g., higher `AllocationCount`).
|
||||||
|
|
||||||
## Detailed Design (summary)
|
## Detailed Design (summary)
|
||||||
-
|
-
|
||||||
- Size classes: levelSizeArray = [64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216] (64B x 4^level)
|
- Size classes: levelSizeArray = [64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216] (64B x 4^level)
|
||||||
@@ -97,7 +110,7 @@ Notes:
|
|||||||
|
|
||||||
1) Compute `level` and `segment` from requested `size`
|
1) Compute `level` and `segment` from requested `size`
|
||||||
2) Try pop bucket (`TryPopLevelForAllocation(level, segment, out entry)`) and escalate:
|
2) Try pop bucket (`TryPopLevelForAllocation(level, segment, out entry)`) and escalate:
|
||||||
- Advance `segment` 0¡ú1¡ú2, then `level++`, until `MaxLevel`
|
- Advance `segment` 0��1��2, then `level++`, until `MaxLevel`
|
||||||
- If still empty: try pop from overflow bucket (L=10, seg=1) or `TryAllocateNew32MBBlock`
|
- If still empty: try pop from overflow bucket (L=10, seg=1) or `TryAllocateNew32MBBlock`
|
||||||
3) On success: bound-check the slice offset; set `entry` to `Alloc` using `SetEntryLevel`
|
3) On success: bound-check the slice offset; set `entry` to `Alloc` using `SetEntryLevel`
|
||||||
4) If remainder exists in the source region, call `SliceMemory(entry->NextNear, remainder)` to produce free chunks into buckets
|
4) If remainder exists in the source region, call `SliceMemory(entry->NextNear, remainder)` to produce free chunks into buckets
|
||||||
@@ -106,7 +119,7 @@ Notes:
|
|||||||
|
|
||||||
- Inputs: `next` entry position, `sizeToSlice`
|
- Inputs: `next` entry position, `sizeToSlice`
|
||||||
- Compute `offset` and `end` relative to base buffer; pick starting level by trailing-zero count of `offset`:
|
- Compute `offset` and `end` relative to base buffer; pick starting level by trailing-zero count of `offset`:
|
||||||
- `i = (BitOperations.TrailingZeroCount(offset) - 6) / 2`, clamped to `¡Ü MaxLevel`
|
- `i = (BitOperations.TrailingZeroCount(offset) - 6) / 2`, clamped to `�� MaxLevel`
|
||||||
- Three phases to cover [offset, end):
|
- Three phases to cover [offset, end):
|
||||||
1) Forward levels i..N-1: for each level size `size` and `upper=size*4`, align to `edge=((offset+upper-1)/upper)*upper`, pack `count = ((min(edge,end) - offset) / size)` blocks
|
1) Forward levels i..N-1: for each level size `size` and `upper=size*4`, align to `edge=((offset+upper-1)/upper)*upper`, pack `count = ((min(edge,end) - offset) / size)` blocks
|
||||||
2) If `i > MaxLevel`: pack in largest upper window on tail
|
2) If `i > MaxLevel`: pack in largest upper window on tail
|
||||||
@@ -119,7 +132,7 @@ Notes:
|
|||||||
- Merge left while neighbor `p` is `Empty`, same `Level`, and within boundary (`AssertBoundary`)
|
- Merge left while neighbor `p` is `Empty`, same `Level`, and within boundary (`AssertBoundary`)
|
||||||
- Remove `p` from bucket (`RemoveFromBucket`), expand current, fix `Position`, unlink `p`
|
- Remove `p` from bucket (`RemoveFromBucket`), expand current, fix `Position`, unlink `p`
|
||||||
- Merge right with neighbor `n` by the same rule
|
- Merge right with neighbor `n` by the same rule
|
||||||
- Optionally promote `Level` if `Size ¡Ý levelSizeArray[originLevel] * 4`
|
- Optionally promote `Level` if `Size �� levelSizeArray[originLevel] * 4`
|
||||||
- Ensure `BucketNode.EntryRef` points to the merged entry; caller re-enqueues into the proper bucket
|
- Ensure `BucketNode.EntryRef` points to the merged entry; caller re-enqueues into the proper bucket
|
||||||
|
|
||||||
### Buckets
|
### Buckets
|
||||||
@@ -140,13 +153,13 @@ Notes:
|
|||||||
|
|
||||||
### Complexity and Invariants
|
### Complexity and Invariants
|
||||||
|
|
||||||
- Allocate/free are O(1) on average with bounded levels (¡Ü10) and constant-time bucket ops
|
- Allocate/free are O(1) on average with bounded levels (��10) and constant-time bucket ops
|
||||||
- Invariants guarded by exceptions (e.g., `HLSFPositionChainBreakException`) and pointer consistency checks
|
- Invariants guarded by exceptions (e.g., `HLSFPositionChainBreakException`) and pointer consistency checks
|
||||||
|
|
||||||
## Profiling (hotspots, current workloads)
|
## Profiling (hotspots, current workloads)
|
||||||
|
|
||||||
- SliceMemory ~22% (self ~17%) ¡ª slicing and bucket enqueue dominate allocation path
|
- SliceMemory ~22% (self ~17%) �� slicing and bucket enqueue dominate allocation path
|
||||||
- MergeAndRemoveFromBuckets ~13% (self ~12%) ¡ª merge + removal dominate free path
|
- MergeAndRemoveFromBuckets ~13% (self ~12%) �� merge + removal dominate free path
|
||||||
- Collect ~7.6% (self ~7.5%) ¡ª low overall cost
|
- Collect ~7.6% (self ~7.5%) �� low overall cost
|
||||||
|
|
||||||
Focus: reduce per-slice math and bucket ops; add fast-paths for aligned regions; batch/lazy removals after merges.
|
Focus: reduce per-slice math and bucket ops; add fast-paths for aligned regions; batch/lazy removals after merges.
|
||||||
@@ -128,6 +128,10 @@
|
|||||||
<RepositoryUrl>https://github.com/Nitload-NSI/StgSharp.git</RepositoryUrl>
|
<RepositoryUrl>https://github.com/Nitload-NSI/StgSharp.git</RepositoryUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionDir Condition="'$(SolutionDir)'=='' Or '$(SolutionDir)'=='*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoOps|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoOps|AnyCPU'">
|
||||||
<Deterministic>False</Deterministic>
|
<Deterministic>False</Deterministic>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -136,11 +140,8 @@
|
|||||||
<Deterministic>False</Deterministic>
|
<Deterministic>False</Deterministic>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoOps|ARM64'">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(DisablePostBuildCopy)'!='true' And '$(SolutionDir)'!='' And '$(SolutionDir)'!='*Undefined*' And !$([System.String]::Copy('$(OutDir)').Contains('StgSharp.Benchmark'))">
|
||||||
<Deterministic>False</Deterministic>
|
<MakeDir Directories="$(SolutionDir)build" />
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
|
||||||
<Exec Command="xcopy /E /I /Y "$(OutDir)" "$(SolutionDir)build"" />
|
<Exec Command="xcopy /E /I /Y "$(OutDir)" "$(SolutionDir)build"" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,15 @@ namespace StgSharp.RegularAnalysis
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public (RegularExpressionLeftBoarderNode left) AddBoarder(string groupName, int groupIndex)
|
||||||
|
{
|
||||||
|
RegularExpressionLeftBoarderNode leftNode = new RegularExpressionLeftBoarderNode(new GroupIndex(groupName, groupIndex));
|
||||||
|
int leftIndex = _nodes.Count;
|
||||||
|
_nodes.Add(leftNode);
|
||||||
|
leftNode.FailNodeIndex = leftIndex; // Point to self by default
|
||||||
|
return (left: leftNode);
|
||||||
|
}
|
||||||
|
|
||||||
public RegularExpressionCounterNode AddCounter(
|
public RegularExpressionCounterNode AddCounter(
|
||||||
int minCount,
|
int minCount,
|
||||||
bool isEager
|
bool isEager
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StgSharpDebug", "StgSharpDe
|
|||||||
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF} = {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}
|
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF} = {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StgSharp.Benchmark", "StgSharp.Benchmark\StgSharp.Benchmark.csproj", "{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}"
|
||||||
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StgSharp.Native", "StgSharp.Native\StgSharp.Native.vcxproj", "{20CBFF26-6746-402E-992C-7B643E9423EB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StgSharp.Native", "StgSharp.Native\StgSharp.Native.vcxproj", "{20CBFF26-6746-402E-992C-7B643E9423EB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0961B2BE-415C-45EA-8607-5B83623B2EF7}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0961B2BE-415C-45EA-8607-5B83623B2EF7}"
|
||||||
@@ -65,6 +67,19 @@ Global
|
|||||||
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.ActiveCfg = Release|ARM64
|
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.Build.0 = Release|ARM64
|
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.ActiveCfg = Release|x64
|
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.PerformanceDebug|x64.ActiveCfg = Release|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.PerformanceDebug|x64.Build.0 = Release|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{0D4D2A8F-2B5B-4F7D-8D63-4A9AF4B4C782}.Release|x64.Build.0 = Release|x64
|
||||||
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.Build.0 = Debug|ARM64
|
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Debug|x64
|
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
|||||||
Reference in New Issue
Block a user