Skip to content

Commit

Permalink
Memory diagnostic support
Browse files Browse the repository at this point in the history
  • Loading branch information
Nice3point committed May 8, 2024
1 parent dfd27e5 commit 4a837a1
Show file tree
Hide file tree
Showing 22 changed files with 401 additions and 130 deletions.
46 changes: 46 additions & 0 deletions source/RevitLookup/Core/Diagnosers/ClockDiagnoser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2003-2024 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.

using System.Diagnostics;

namespace RevitLookup.Core.Diagnosers;

public class ClockDiagnoser
{
private readonly Stopwatch _clock = new();

public void Start()
{
_clock.Start();
}

public void Stop()
{
_clock.Stop();
}

public TimeSpan GetElapsed()
{
var elapsed = _clock.Elapsed;
_clock.Reset();

return elapsed;
}
}
57 changes: 57 additions & 0 deletions source/RevitLookup/Core/Diagnosers/MemoryDiagnoser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2003-2024 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.

namespace RevitLookup.Core.Diagnosers;

public class MemoryDiagnoser
{
private long _initialAllocatedBytes;
private long _finalAllocatedBytes;

public void Start()
{
_initialAllocatedBytes = GetTotalAllocatedBytes();
}

public void Stop()
{
_finalAllocatedBytes = GetTotalAllocatedBytes();
}

public long GetAllocatedBytes()
{
var allocatedBytes = _finalAllocatedBytes - _initialAllocatedBytes;

_finalAllocatedBytes = 0;
_initialAllocatedBytes = 0;

return allocatedBytes;
}

private static long GetTotalAllocatedBytes()
{
// We don't need to run GC.Collect();
// GC.GetTotalAllocatedBytes() is not valid for this case.
// AppDomain.MonitoringIsEnabled is not valid for this case.
// Ref: https://github.com/dotnet/BenchmarkDotNet/blob/master/src/BenchmarkDotNet/Engines/GcStats.cs

return GC.GetAllocatedBytesForCurrentThread();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

using RevitLookup.Core.Objects;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,23 @@
// (Rights in Technical Data and Computer Software), as applicable.

using System.Reflection;
using System.Runtime;
using RevitLookup.Core.Objects;
using RevitLookup.Core.Utils;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder
{
private IList<Descriptor> BuildInstanceObject(Type type)
{
var types = GetTypeHierarchy(type);

for (var i = types.Count - 1; i >= 0; i--)
{
_type = types[i];
_currentDescriptor = DescriptorUtils.FindSuitableDescriptor(_obj, _type);

var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
if (_settings.IncludeStatic) flags |= BindingFlags.Static;
if (_settings.IncludePrivate) flags |= BindingFlags.NonPublic;
Expand All @@ -43,15 +45,15 @@ private IList<Descriptor> BuildInstanceObject(Type type)
AddFields(flags);
AddEvents(flags);
AddExtensions();

_depth--;
}

AddEnumerableItems();

return _descriptors;
}

private List<Type> GetTypeHierarchy(Type type)
{
var types = new List<Type>();
Expand All @@ -60,23 +62,23 @@ private List<Type> GetTypeHierarchy(Type type)
types.Add(type);
type = type.BaseType;
}

if (_settings.IncludeRootHierarchy) types.Add(type);

return types;
}

private IList<Descriptor> BuildStaticObject(Type type)
{
_type = type;

var flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly;
if (_settings.IncludePrivate) flags |= BindingFlags.NonPublic;

AddProperties(flags);
AddMethods(flags);
AddFields(flags);

return _descriptors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

using System.Collections;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Reflection;
using RevitLookup.Core.Utils;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,49 @@
using RevitLookup.Core.Contracts;
using RevitLookup.Core.Objects;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder : IExtensionManager
{
private void AddExtensions()
{
if (!_settings.IncludeExtensions) return;
if (_currentDescriptor is not IDescriptorExtension extension) return;

extension.RegisterExtensions(this);
}

public void Register<T>(T value, Action<DescriptorExtension<T>> extension)
{
var descriptorExtension = new DescriptorExtension<T>
{
Value = value,
Context = Context
};

_tracker.Start();

try
{
extension.Invoke(descriptorExtension);
Evaluate(descriptorExtension, extension);
WriteDescriptor(descriptorExtension.Name, descriptorExtension.Result);
}
catch (Exception exception)
{
WriteDescriptor(descriptorExtension.Name, exception);
}
}

private void Evaluate<T>(DescriptorExtension<T> descriptorExtension, Action<DescriptorExtension<T>> extension)
{
try
{
_clockDiagnoser.Start();
_memoryDiagnoser.Start();
extension.Invoke(descriptorExtension);
}
finally
{
_tracker.Stop();
_memoryDiagnoser.Stop();
_clockDiagnoser.Stop();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,31 @@

using System.Reflection;

namespace RevitLookup.Core.Metadata;
namespace RevitLookup.Core.Engine;

public sealed partial class DescriptorBuilder
{
private void AddFields(BindingFlags bindingFlags)
{
if (!_settings.IncludeFields) return;

var members = _type.GetFields(bindingFlags);
foreach (var member in members)
{
if (member.IsSpecialName) continue;
_tracker.Start();
var value = member.GetValue(_obj);
_tracker.Stop();

var value = Evaluate(member);
WriteDescriptor(member, value, null);
}
}

private object Evaluate(FieldInfo member)
{
_clockDiagnoser.Start();
_memoryDiagnoser.Start();
var value = member.GetValue(_obj);
_memoryDiagnoser.Stop();
_clockDiagnoser.Stop();
return value;
}
}
Loading

0 comments on commit 4a837a1

Please sign in to comment.