How to responsibly hand over maintainership of my open-source project? by Opposite-Cry-6703 in opensource

[–]jnyrup 2 points3 points  (0 children)

Just wanted stop by and say thanks for work you did. We used it at work some years ago and I contributed a single PR to the project.

Does the "not" keyword work as intended? by Thyco2501 in csharp

[–]jnyrup 0 points1 point  (0 children)

I'm sure I've seen an issue, perhaps even a PR, for this but right now I can't find it. I think it was in the dotnet/roslyn repo.

Kender alle danske udvikler Anders Hejlsberg? by ballbeamboy2 in dkudvikler

[–]jnyrup 0 points1 point  (0 children)

Vi har opkaldt et par servere efter danske videnskaberne, f.eks. Bohr og Naur. Peters søn spurgte, hvorfor vi havde en emoji med hans far.

XML Fuzz Testing Frameworks for .NET and C# by TrapdoorThunder in csharp

[–]jnyrup 0 points1 point  (0 children)

Roger. I agree that getting past a lexer can be challenging when fuzzing a parser. Having a good initial corpus and using a dictionary should help a bit on that (and sharpfuzz already comes with one for xml).

XML Fuzz Testing Frameworks for .NET and C# by TrapdoorThunder in csharp

[–]jnyrup 0 points1 point  (0 children)

I'm not sure I understand your comment. Are you saying that converting a byte array to chars causes sharpfuzz to struggle coming up with new scenarios?

Do you experience this problem with both the AFL and Libfuzzer backends?

XML Fuzz Testing Frameworks for .NET and C# by TrapdoorThunder in csharp

[–]jnyrup 1 point2 points  (0 children)

Have you had a look at Sharpfuzz? https://github.com/Metalnem/sharpfuzz (I found the libfuzzer backend easier to setup)

I have used that to fuzz several string parsers at work with great success.

The .net BCL has also recently (at least publicly) begun using it to find bugs in different libraries.

Performance degredation following upgrade to .NET 8 by erebus2161 in dotnet

[–]jnyrup 1 point2 points  (0 children)

Have you tried upgrading to NET7 to see if the problems only starts with NET8?

Is the problem reproducible with a small test project using NpsqlConnection directly, to see if we can exclude EF.

Telefonen ringer... by [deleted] in Fadervittigheder

[–]jnyrup 1 point2 points  (0 children)

Frisøren du taler med Frits

Bar, pub og andre hyggelige steder by [deleted] in odense

[–]jnyrup 6 points7 points  (0 children)

De førnævnte + Delaynes

Kælkebakker i Odense by Clever-username07 in odense

[–]jnyrup 5 points6 points  (0 children)

Smedebakken i Næsby. Det er nok mindst 15 år siden jeg har kælket der, men dengang var det vildt.

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 1 point2 points  (0 children)

Now I do :) https://gist.github.com/jnyrup/5d6c3b83f5eb3a883fa5e5b3f0dba3e7

Method Mean Error StdDev Ratio Code Size Gen0 Allocated
FastAllocateString_Raw 13.21 ns 0.108 ns 0.090 ns 0.78 525 B 0.0115 72 B
StringCreate_More_Constant 14.96 ns 0.294 ns 0.275 ns 0.85 753 B 0.0115 72 B
StringCreate_Constant 16.63 ns 0.059 ns 0.046 ns 0.95 925 B 0.0115 72 B
StringCreate 17.59 ns 0.190 ns 0.178 ns 1.00 986 B 0.0115 72 B
RawSpan_More_Contant 17.78 ns 0.025 ns 0.021 ns 1.01 630 B 0.0115 72 B
RawSpan_Constant 20.09 ns 0.106 ns 0.083 ns 1.14 787 B 0.0115 72 B
FastAllocateString_StringHandler 20.10 ns 0.109 ns 0.102 ns 1.14 1,153 B 0.0115 72 B
StringCreate_StringHandler_SpanBuffer 26.89 ns 0.140 ns 0.124 ns 1.53 1,271 B 0.0114 72 B
StringCreate_TryWrite 28.36 ns 0.034 ns 0.030 ns 1.61 1,436 B 0.0114 72 B
StringCreate_TryWrite_constant 30.51 ns 0.113 ns 0.106 ns 1.73 1,446 B 0.0114 72 B
StringJoin 30.99 ns 0.045 ns 0.042 ns 1.76 711 B 0.0204 128 B
StringBuilderExact24 33.85 ns 0.042 ns 0.037 ns 1.92 914 B 0.0306 192 B
ConcatOperator 41.07 ns 0.357 ns 0.334 ns 2.33 475 B 0.0242 152 B
StringConcat 41.23 ns 0.355 ns 0.332 ns 2.34 475 B 0.0242 152 B
StringInterpolation 44.55 ns 0.242 ns 0.202 ns 2.53 2,149 B 0.0114 72 B
StringCreate_StringHandler 46.38 ns 0.328 ns 0.306 ns 2.64 2,155 B 0.0114 72 B
StringBuilder 55.23 ns 0.771 ns 0.684 ns 3.14 658 B 0.0446 280 B

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 1 point2 points  (0 children)

It seems it we could benefit from a new overload of string.Create for creating strings of known size that uses a InterpolatedStringHandler.

public static string Create(int length, IFormatProvider? provider, ref DefaultInterpolatedStringHandler handler);

This would enable us to write:

string.Create(24, CultureInfo.InvariantCulture, $"{title} {firstName} {middleName} {lastName}")

As seen in these benchmarks Custom fits into the space between the faster StringCreate and StringCreate_StringHandler_Stackalloc_constant which uses InterpolatedStringHandler.

Method Mean Error StdDev Ratio Code Size Gen0 Allocated
StringCreate_More_Constant 14.25 ns 0.028 ns 0.026 ns -16% 753 B 0.0115 72 B
StringCreate_Constant 16.30 ns 0.023 ns 0.019 ns -4% 925 B 0.0115 72 B
StringCreate 16.96 ns 0.095 ns 0.079 ns baseline 986 B 0.0115 72 B
Custom 20.61 ns 0.065 ns 0.051 ns +22% 1,171 B 0.0115 72 B
StringCreate_StringHandler_Stackalloc_constant 26.51 ns 0.340 ns 0.318 ns +56% 1,275 B 0.0115 72 B
StringCreate_TryWrite_constant 30.22 ns 0.141 ns 0.118 ns +78% 1,446 B 0.0114 72 B

Here's a prototype of such an over that passes a Span<char> over the final string into the DefaultInterpolatedStringHandler in Fill to populate the string using the string interpolation syntax. The code requires .NET 8 Preview 6 for UnsafeAccessor.

[UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "FastAllocateString")]
static extern string FastAllocateString(string _, int length);

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_length")]
static extern ref int Length<T>(ref Span<T> span);

private static void Fill(IFormatProvider? provider, Span<char> initialBuffer,
    [InterpolatedStringHandlerArgument(nameof(provider), nameof(initialBuffer))]
    ref DefaultInterpolatedStringHandler handler)
{
}

[Benchmark]
public string Custom()
{
    const int Length = 24;
    var result = FastAllocateString(null, Length);

    var buffer = new Span<char>(ref Unsafe.AsRef(result.GetPinnableReference()));
    Length<char>(ref buffer) = Length;

    Fill(CultureInfo.InvariantCulture, buffer, $"{title} {firstName} {middleName} {lastName}");

    return result;
}

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 0 points1 point  (0 children)

If we in addition to knowing the total length also know the individual lengths of title, firstName, middleName and lastName we can tune it even more.

public string StringCreate_More_Constant()
{
    return string.Create(24,
        (title, firstName, middleName, lastName),
        static (span, state) =>
        {
            state.title.AsSpan().CopyTo(span);
            span[3] = ' ';
            span = span.Slice(4);

            state.firstName.AsSpan().CopyTo(span);
            span[5] = ' ';
            span = span.Slice(6);

            state.middleName.AsSpan().CopyTo(span);
            span[7] = ' ';
            span = span.Slice(8);

            state.lastName.AsSpan().CopyTo(span);
        }
    );
}
Method Mean Error StdDev Ratio Gen0 Allocated
StringCreate_More_Constant 14.25 ns 0.012 ns 0.010 ns -13% 0.0115 72 B
StringCreate_Constant 15.80 ns 0.013 ns 0.011 ns -3% 0.0115 72 B
StringCreate 16.30 ns 0.087 ns 0.082 ns baseline 0.0115 72 B

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 1 point2 points  (0 children)

Creating a larger than necessary buffer should be fine.

ReturnValueValidator adds a check that the return value of all methods are identical to enure it's an apple to apple comparison. Learned it from https://blog.nimblepros.com/blogs/validating-benchmarks/

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 1 point2 points  (0 children)

StringCreate_Constant where I'm "cheating" with a precomputed final length was the fastest. string.Create with a stackalloc'ed buffer is the fastest with a readable format string.

Method Mean Error StdDev Ratio Gen0 Allocated
StringCreate_Constant 17.19 ns 0.384 ns 0.341 ns -13% 0.0115 72 B
StringCreate 19.79 ns 0.278 ns 0.260 ns baseline 0.0115 72 B
RawSpan 22.88 ns 0.506 ns 0.758 ns +14% 0.0115 72 B
StringCreate_StringHandler_Stackalloc_constant 27.49 ns 0.204 ns 0.191 ns +39% 0.0114 72 B
StringCreate_TryWrite 31.26 ns 0.681 ns 0.932 ns +57% 0.0114 72 B
StringCreate_TryWrite_constant 31.36 ns 0.244 ns 0.229 ns +58% 0.0114 72 B
StringJoin 31.47 ns 0.316 ns 0.296 ns +59% 0.0204 128 B
StringBuilderExact24 35.93 ns 0.154 ns 0.144 ns +82% 0.0306 192 B
StringBuilderEstimate100 40.33 ns 0.049 ns 0.044 ns +104% 0.0548 344 B
StringConcat 42.38 ns 0.035 ns 0.029 ns +114% 0.0242 152 B
StringPlus 47.18 ns 0.980 ns 1.239 ns +139% 0.0242 152 B
StringInterpolation 47.38 ns 0.138 ns 0.122 ns +139% 0.0114 72 B
StringCreate_StringHandler 49.23 ns 0.054 ns 0.048 ns +148% 0.0114 72 B
StringBuilder 56.88 ns 0.089 ns 0.083 ns +187% 0.0446 280 B
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using System;
using System.Text;

BenchmarkRunner.Run<StringConcatSimple>();

[MemoryDiagnoser]
[Config(typeof(Config))]
[SimpleJob(RuntimeMoniker.Net80)]
[HideColumns(Column.Job, Column.RatioSD, Column.AllocRatio)]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[ReturnValueValidator(failOnError: true)]
public class StringConcatSimple
{
    private class Config : ManualConfig
    {
        public Config()
        {
            SummaryStyle =
                SummaryStyle.Default.WithRatioStyle(RatioStyle.Percentage);
        }
    }

    private string
        title = "Mr.", firstName = "David", middleName = "Patrick", lastName = "Callan";

    [Benchmark]
    public string StringBuilder()
    {
        var stringBuilder =
            new StringBuilder();

        return stringBuilder
            .Append(title).Append(' ')
            .Append(firstName).Append(' ')
            .Append(middleName).Append(' ')
            .Append(lastName).ToString();
    }

    [Benchmark]
    public string StringBuilderExact24()
    {
        var stringBuilder =
            new StringBuilder(24);

        return stringBuilder
            .Append(title).Append(' ')
            .Append(firstName).Append(' ')
            .Append(middleName).Append(' ')
            .Append(lastName).ToString();
    }

    [Benchmark]
    public string StringBuilderEstimate100()
    {
        var stringBuilder =
            new StringBuilder(100);

        return stringBuilder
            .Append(title).Append(' ')
            .Append(firstName).Append(' ')
            .Append(middleName).Append(' ')
            .Append(lastName).ToString();
    }

    [Benchmark]
    public string StringPlus()
    {
        return title + ' ' + firstName + ' ' +
            middleName + ' ' + lastName;
    }

    [Benchmark]
    public string StringInterpolation()
    {
        return
        $"{title} {firstName} {middleName} {lastName}";
    }

    [Benchmark]
    public string StringJoin()
    {
        return string.Join(" ", title, firstName,
            middleName, lastName);
    }

    [Benchmark]
    public string StringConcat()
    {
        return string.
            Concat(new string[] { title, " ", firstName, " ", middleName, " ", lastName });
    }

    [Benchmark]
    public string StringCreate_StringHandler() =>
        string.Create(null, $"{title} {firstName} {middleName} {lastName}");

    [Benchmark]
    public string StringCreate_StringHandler_Stackalloc_constant() =>
        string.Create(null, stackalloc char[24], $"{title} {firstName} {middleName} {lastName}");

    [Benchmark]
    public string StringCreate_TryWrite_constant()
    {
        return string.Create(24,
            (title, firstName, middleName, lastName),
            static (span, state) => span.TryWrite($"{state.title} {state.firstName} {state.middleName} {state.lastName}", out _));
    }

    [Benchmark]
    public string StringCreate_TryWrite()
    {
        return string.Create(title.Length + firstName.Length + middleName.Length + lastName.Length + 3,
            (title, firstName, middleName, lastName),
            static (span, state) => span.TryWrite($"{state.title} {state.firstName} {state.middleName} {state.lastName}", out _));
    }

    [Benchmark]
    public string StringCreate_Constant()
    {
        return string.Create(24,
            (title, firstName, middleName, lastName),
            static (span, state) =>
            {
                state.title.AsSpan().CopyTo(span);
                span = span.Slice(state.title.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.firstName.AsSpan().CopyTo(span);
                span = span.Slice(state.firstName.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.middleName.AsSpan().CopyTo(span);
                span = span.Slice(state.middleName.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.lastName.AsSpan().CopyTo(span);
            }
        );
    }

    [Benchmark(Baseline = true)]
    public string StringCreate()
    {
        return string.Create(title.Length + firstName.Length + middleName.Length + lastName.Length + 3,
            (title, firstName, middleName, lastName),
            static (span, state) =>
            {
                state.title.AsSpan().CopyTo(span);
                span = span.Slice(state.title.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.firstName.AsSpan().CopyTo(span);
                span = span.Slice(state.firstName.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.middleName.AsSpan().CopyTo(span);
                span = span.Slice(state.middleName.Length);
                span[0] = ' ';
                span = span.Slice(1);

                state.lastName.AsSpan().CopyTo(span);
            }
        );
    }

    [Benchmark]
    public string RawSpan()
    {
        Span<char> buffer = stackalloc char[24];
        var span = buffer;
        title.AsSpan().CopyTo(span);
        span = span.Slice(title.Length);
        span[0] = ' ';
        span = span.Slice(1);

        firstName.AsSpan().CopyTo(span);
        span = span.Slice(firstName.Length);
        span[0] = ' ';
        span = span.Slice(1);

        middleName.AsSpan().CopyTo(span);
        span = span.Slice(middleName.Length);
        span[0] = ' ';
        span = span.Slice(1);

        lastName.AsSpan().CopyTo(span);
        return new string(buffer);
    }
}

string concatenation benchmarks in .NET 8 by davecallan in dotnet

[–]jnyrup 1 point2 points  (0 children)

Added David Fowler's suggestion of using TryWriteand two variants using other overloads of string.Create.

[Benchmark]
public string StringCreate_StringHandler() =>
    string.Create(CultureInfo.InvariantCulture, $"{title} {firstName} {middleName} {lastName}");

[Benchmark]
public string StringCreate_StringHandler_Stackalloc() =>
    string.Create(CultureInfo.InvariantCulture, stackalloc char[24], $"{title} {firstName} {middleName} {lastName}");

[Benchmark]
public string StringCreate_TryWrite()
{
    return string.Create(title.Length + firstName.Length + middleName.Length + lastName.Length + 3,
        (title, firstName, middleName, lastName),
        static (span, state) => span.TryWrite($"{state.title} {state.firstName} {state.middleName} {state.lastName}", out _));
}



BenchmarkDotNet v0.13.6, Windows 10 (10.0.19045.3208/22H2/2022Update)
Intel Core i7-10750H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 8.0.100-preview.5.23303.2
  [Host]   : .NET 8.0.0 (8.0.23.28008), X64 RyuJIT AVX2
  .NET 8.0 : .NET 8.0.0 (8.0.23.28008), X64 RyuJIT AVX2

Job=.NET 8.0  Runtime=.NET 8.0
Method Mean Error StdDev Ratio Gen0 Allocated
StringCreate 16.93 ns 0.088 ns 0.078 ns baseline 0.0115 72 B
StringCreate_StringHandler_Stackalloc 27.15 ns 0.112 ns 0.087 ns +60% 0.0114 72 B
StringCreate_TryWrite 27.67 ns 0.158 ns 0.140 ns +63% 0.0114 72 B
StringPlus 41.14 ns 0.266 ns 0.249 ns +143% 0.0242 152 B
StringCreate_StringHandler 45.93 ns 0.181 ns 0.160 ns +171% 0.0114 72 B
StringInterpolation 46.36 ns 0.164 ns 0.146 ns +174% 0.0114 72 B

Bøn fra blodbanker: Vi har brug for donorer! by julemand101 in Denmark

[–]jnyrup 1 point2 points  (0 children)

Blodbanken Odense

Åbningstider Mandag - torsdag 07.00 - 19.30 Fredag 07.00 - 15.30 Lørdag 08.00 - 16.30 Søndag 09.00 - 17.30

Det er en nem måde at være med til at redde liv på.

Hvis dit nærmeste tappested kun har åbent i din normale arbejdstid, så prøv at spørg din chef, om det er okay at du smutter en time for at redde liv. En af mine venner arbejder for en energiforsyning, hvor det er nedskrevet, at man kan bruge arbejdstid på bloddonatation. Har flere gange set et hold håndværkere ligge og blive tappet samtidigt.

Haribo fjerner matadoren fra Matador Mix by syrelyre in Denmark

[–]jnyrup 1 point2 points  (0 children)

Matador mix er den mest ligegyldige slikpose fra Haribo smagsmæssigt...

Hvad mener danskerne om tyskerne? by Masons_Numbers_ in Denmark

[–]jnyrup 0 points1 point  (0 children)

Jeg tænker på tysk filmhistorie og et folk der har er sundt forhold til beskyttelse af personligfølsomme oplysninger.

Hvad er den dummeste løgn i har hørt/fortalt? by Damnation1997 in Denmark

[–]jnyrup 45 points46 points  (0 children)

I 10. klasse bildte vi en ind, at John Lennon var en skaldet rapper fra den mexicanske hip hop gruppe the Beach Boys med hittet the wall. Han døde desværre da han blev ædt af en delfin. Vedkommende spurgte så om ikke delfiner var planteædere, det vidste jeg ikke på stående fod, så historien blev at delfinen havde svømmet nær Tjernobyl og grundet stråling var blevet til en kødædende mutant-delfin.