Skip to content

Conversation

udaken
Copy link
Contributor

@udaken udaken commented Jul 8, 2020

IntPtr

IntPtr does not support formatting, but it is the "basic" numeric type of the system.
However, when used with ZString, it causes a heap allocation.
I believe there needs to be built-in support for it.

The specification of IntPtr.ToString() is quoted below.

If the value of the Size property for this instance is 4, then this method is equivalent to Int32.ToString; otherwise, this method is equivalent to Int64.ToString.

Before

Method Mean Error Gen 0 Gen 1 Gen 2 Allocated
StringBuilderIntPtr 187.2 ns NA 0.0210 - - 176 B
ZStringBuilderIntPtr 270.5 ns NA 0.0124 - - 104 B

After

Method Mean Error Gen 0 Gen 1 Gen 2 Allocated
StringBuilderIntPtr 182.0 ns NA 0.0210 - - 176 B
ZStringBuilderIntPtr 263.1 ns NA 0.0048 - - 40 B

The benchmark code is as below.

using BenchmarkDotNet.Attributes;
using Cysharp.Text;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using System.Buffers;

namespace PerfBenchmark.Benchmarks
{
    [Config(typeof(BenchmarkConfig))]
    public class IntPtrFormat
    {
        [Benchmark]
        public string StringBuilderIntPtr()
        {
            return String.Format("{0}{1}{2}", new IntPtr(-1), IntPtr.Zero, new IntPtr(12345));
        }
        [Benchmark]
        public string ZStringBuilderIntPtr()
        {
            return ZString.Format("{0}{1}{2}", new IntPtr(-1), IntPtr.Zero, new IntPtr(12345));
        }

    }
}
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19042
AMD Ryzen 7 3700X, 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.400-preview-015178
  [Host]   : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
  ShortRun : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT

Job=ShortRun  IterationCount=1  LaunchCount=1
WarmupCount=1

Nullable<T>

String.Format supports formatting for Nullable types.

Console.WriteLine(String.Format("{0:X}", (int?)100));
// ->64

In ZString Ver2.1.3, heap allocation occurs.

Before

Method Mean Error Gen 0 Gen 1 Gen 2 Allocated
NullableFormat 394.1 ns NA 0.0210 - - 176 B
ZNullableFormat 286.5 ns NA 0.0296 - - 248 B

After

Method Mean Error Gen 0 Gen 1 Gen 2 Allocated
NullableFormat 395.9 ns NA 0.0210 - - 176 B
ZNullableFormat 330.6 ns NA 0.0143 - - 120 B

The benchmark code is as below.

using BenchmarkDotNet.Attributes;
using Cysharp.Text;
using System;
using System.Text;


namespace PerfBenchmark.Benchmarks
{
    [Config(typeof(BenchmarkConfig))]
    public class NullableFormatBenchMark
    {

        StringBuilder bcl = new StringBuilder();
        long? l = 123456L;
        Guid? guid = Guid.NewGuid();
        int? i = null;

        [Benchmark]
        public string NullableFormat()
        {
            return String.Format("{0:N}{1}{2:X}", l, guid, i);
        }
        [Benchmark]
        public string ZNullableFormat()
        {
            return ZString.Format("{0:N}{1}{2:X}", l, guid, i);
        }
    }
}
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19042
AMD Ryzen 7 3700X, 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.400-preview-015178
  ShortRun : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT

Job=ShortRun  IterationCount=1  LaunchCount=1
WarmupCount=1

IFormattable

For convenience, If you implement IFormattable, call ToString(string format, IFormatProvider formatProvider).
However, allocation will occur.

@udaken udaken changed the title Disable allocation when using IntPtr. Removes allocation when using IntPtr. Jul 8, 2020
@udaken udaken changed the title Removes allocation when using IntPtr. Removes allocation when using IntPtr and Nullable<T>. Jul 11, 2020
@udaken udaken force-pushed the Built-in-support-for-IntPtr-UIntPtr branch from 8f708a0 to 369667c Compare July 11, 2020 05:06
@udaken
Copy link
Contributor Author

udaken commented Jul 31, 2020

@neuecc Thanks for the review.
Thanks for the review.
I ReRun Custom Tool and fixed the conflict.

@neuecc neuecc merged commit ea6879d into Cysharp:master Aug 3, 2020
@udaken udaken deleted the Built-in-support-for-IntPtr-UIntPtr branch August 3, 2020 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants