StringBuilderPool.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System.Diagnostics;
  3. using System.Text;
  4. namespace Jint.Pooling
  5. {
  6. /// <summary>
  7. /// Pooling of StringBuilder instances.
  8. /// </summary>
  9. internal static class StringBuilderPool
  10. {
  11. private static readonly ConcurrentObjectPool<StringBuilder> _pool;
  12. static StringBuilderPool()
  13. {
  14. _pool = new ConcurrentObjectPool<StringBuilder>(() => new StringBuilder());
  15. }
  16. public static BuilderWrapper Rent()
  17. {
  18. var builder = _pool.Allocate();
  19. Debug.Assert(builder.Length == 0);
  20. return new BuilderWrapper(builder, _pool);
  21. }
  22. internal readonly struct BuilderWrapper : IDisposable
  23. {
  24. public readonly StringBuilder Builder;
  25. private readonly ConcurrentObjectPool<StringBuilder> _pool;
  26. public BuilderWrapper(StringBuilder builder, ConcurrentObjectPool<StringBuilder> pool)
  27. {
  28. Builder = builder;
  29. _pool = pool;
  30. }
  31. public int Length => Builder.Length;
  32. public override string ToString()
  33. {
  34. return Builder.ToString();
  35. }
  36. public void Dispose()
  37. {
  38. var builder = Builder;
  39. // do not store builders that are too large.
  40. if (builder.Capacity <= 1024 * 1024)
  41. {
  42. builder.Clear();
  43. _pool.Free(builder);
  44. }
  45. else
  46. {
  47. _pool.ForgetTrackedObject(builder);
  48. }
  49. }
  50. }
  51. }
  52. }