diff --git a/index.json b/index.json index eb5335a..51883a2 100644 --- a/index.json +++ b/index.json @@ -242,7 +242,7 @@ "topics/benchmarks.html": { "href": "topics/benchmarks.html", "title": "Addax - Benchmarks", - "keywords": "Addax - Benchmarks The following benchmarks reflect the approximate time and memory required to process 1,048,576 fields: .NET 8.0.0 (8.0.23.53103) | Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| | 'read field: empty' | 6,738.6 μs | 6,756.1 μs | 6,609.2 μs | 6,906.1 μs | 148.40 | 389 B | | 'read field: regular' | 17,973.0 μs | 17,939.9 μs | 17,783.3 μs | 18,286.9 μs | 55.64 | 406 B | | 'read field: escaped' | 33,030.4 μs | 32,845.8 μs | 32,497.5 μs | 34,234.7 μs | 30.28 | 430 B | | 'read field: empty (async)' | 7,253.0 μs | 7,235.0 μs | 7,203.0 μs | 7,328.2 μs | 137.87 | 389 B | | 'read field: regular (async)' | 18,483.3 μs | 18,481.3 μs | 18,430.0 μs | 18,540.9 μs | 54.10 | 406 B | | 'read field: escaped (async)' | 35,669.9 μs | 35,640.6 μs | 35,502.1 μs | 35,841.1 μs | 28.03 | 430 B | | Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| | 'write field: empty' | 5,341.3 μs | 5,352.1 μs | 5,256.9 μs | 5,423.7 μs | 187.22 | 277 B | | 'write field: regular' | 9,236.5 μs | 9,238.9 μs | 9,157.1 μs | 9,351.6 μs | 108.27 | 395 B | | 'write field: escaped' | 14,607.3 μs | 14,603.4 μs | 14,588.9 μs | 14,633.8 μs | 68.46 | 395 B | | 'write field: empty (async)' | 10,284.7 μs | 10,270.8 μs | 10,175.8 μs | 10,418.4 μs | 97.23 | 283 B | | 'write field: regular (async)' | 14,646.5 μs | 14,634.4 μs | 14,588.9 μs | 14,711.1 μs | 68.28 | 385 B | | 'write field: escaped (async)' | 20,475.2 μs | 20,501.8 μs | 20,289.4 μs | 20,557.1 μs | 48.84 | 406 B | Mean : Arithmetic mean of all measurements Error : Half of 99.9% confidence interval StdDev : Standard deviation of all measurements Median : Value separating the higher half of all measurements (50th percentile) Min : Minimum Max : Maximum Op/s : Operation per second Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B) 1 μs : 1 Microsecond (0.000001 sec)" + "keywords": "Addax - Benchmarks The following benchmarks reflect the approximate time and memory required to process 1,048,576 fields: .NET 8.0.0 (8.0.23.53103) | Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| | 'read field: empty' | 7,232.5 us | 7,256.1 us | 7,150.9 us | 7,336.2 us | 138.27 | 389 B | | 'read field: regular' | 18,323.2 us | 18,279.8 us | 18,152.8 us | 18,554.7 us | 54.58 | 406 B | | 'read field: escaped' | 50,433.9 us | 50,409.4 us | 50,219.8 us | 50,809.0 us | 19.83 | 447 B | | 'read field: empty (async)' | 7,614.2 us | 7,637.3 us | 7,487.2 us | 7,747.4 us | 131.33 | 389 B | | 'read field: regular (async)' | 19,077.0 us | 19,116.3 us | 18,918.2 us | 19,231.4 us | 52.42 | 406 B | | 'read field: escaped (async)' | 51,548.7 us | 51,465.8 us | 51,305.2 us | 51,979.0 us | 19.40 | 395 B | | Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| | 'write field: empty' | 5,401.2 us | 5,387.5 us | 5,325.0 us | 5,523.5 us | 185.15 | 389 B | | 'write field: regular' | 10,059.8 us | 10,060.6 us | 10,031.1 us | 10,101.1 us | 99.41 | 385 B | | 'write field: escaped' | 14,677.5 us | 14,675.2 us | 14,640.0 us | 14,733.7 us | 68.13 | 395 B | | 'write field: empty (async)' | 10,243.5 us | 10,240.5 us | 10,199.4 us | 10,303.8 us | 97.62 | 395 B | | 'write field: regular (async)' | 15,227.2 us | 15,232.5 us | 15,163.4 us | 15,290.2 us | 65.67 | 395 B | | 'write field: escaped (async)' | 19,948.4 us | 19,946.0 us | 19,895.2 us | 19,998.9 us | 50.13 | 406 B | Mean : Arithmetic mean of all measurements Error : Half of 99.9% confidence interval StdDev : Standard deviation of all measurements Median : Value separating the higher half of all measurements (50th percentile) Min : Minimum Max : Maximum Op/s : Operation per second Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B) 1 μs : 1 Microsecond (0.000001 sec)" }, "topics/extensibility/record-handlers.html": { "href": "topics/extensibility/record-handlers.html", @@ -252,12 +252,12 @@ "topics/extensibility/value-converters.html": { "href": "topics/extensibility/value-converters.html", "title": "Addax - Value Converters", - "keywords": "Addax - Value Converters A custom converter A complete example of a custom value converter that handles System.DateTime values represented as Unix timestamps: C# F# internal class UnixDateTimeConverter : TabularConverter { public override bool TryFormat(DateTime value, Span destination, IFormatProvider? provider, out int charsWritten) { var seconds = (long)(value.ToUniversalTime() - DateTime.UnixEpoch).TotalSeconds; return seconds.TryFormat(destination, out charsWritten, \"g\", provider); } public override bool TryParse(ReadOnlySpan source, IFormatProvider? provider, out DateTime value) { if (long.TryParse(source, NumberStyles.Integer, provider, out var seconds)) { value = DateTime.UnixEpoch.AddSeconds(seconds); return true; } else { value = default; return false; } } } type internal UnixDateTimeConverter() = inherit TabularConverter() override this.TryFormat(value, destination, provider, charsWritten) = let seconds = int64 (value.ToUniversalTime () - DateTime.UnixEpoch).TotalSeconds seconds.TryFormat(destination, &charsWritten, \"g\", provider) override this.TryParse(source, provider, value) = let mutable seconds = Unchecked.defaultof if Int64.TryParse(source, NumberStyles.Integer, provider, &seconds) then value <- DateTime.UnixEpoch.AddSeconds (float seconds) true else value <- Unchecked.defaultof false High-level API (C#) Low-level API (C#) High-level API (F#) Low-level API (F#) var dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"'); using (var writer = new TabularWriter(File.Create(\"books.csv\"), dialect)) { var book1 = new Book { Author = \"Lewis Carroll\", Title = \"Alice's Adventures in Wonderland\", Published = new(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc) }; writer.WriteRecord(book1); var book2 = new Book { Author = \"H. G. Wells\", Title = \"The Time Machine\", Published = new(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc) }; writer.WriteRecord(book2); } using (var reader = new TabularReader(File.OpenRead(\"books.csv\"), dialect)) { while (reader.TryReadRecord()) { var book = reader.CurrentRecord; Console.WriteLine($\"{book.Author} '{book.Title}' ({book.Published})\"); } } [TabularRecord] internal struct Book { [TabularFieldOrder(0)] public string? Author; [TabularFieldOrder(1)] public string? Title; [TabularConverter(typeof(UnixDateTimeConverter))] [TabularFieldOrder(2)] public DateTime? Published; } using Addax.Formats.Tabular; var converter = new UnixDateTimeConverter(); var dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"'); using (var writer = new TabularWriter(File.Create(\"books.csv\"), dialect)) { writer.WriteString(\"Lewis Carroll\"); writer.WriteString(\"Alice's Adventures in Wonderland\"); writer.Write(new(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc), converter); writer.FinishRecord(); writer.WriteString(\"H. G. Wells\"); writer.WriteString(\"The Time Machine\"); writer.Write(new(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc), converter); writer.FinishRecord(); } using (var reader = new TabularReader(File.OpenRead(\"books.csv\"), dialect)) { while (reader.TryPickRecord()) { reader.TryReadField(); reader.TryGetString(out var field0); reader.TryReadField(); reader.TryGetString(out var field1); reader.TryReadField(); reader.TryGet(converter, out var field2); Console.WriteLine($\"{field0} '{field1}' ({field2})\"); } } Consider adding extension methods for using a custom value converter with the low-level API: internal static class TabularUnixDateTimeExtensions { private static readonly UnixDateTimeConverter s_converter = new(); public static bool TryGetUnixDateTime(this TabularReader reader, out DateTime value) { return reader.TryGet(s_converter, out value); } public static DateTime GetUnixDateTime(this TabularReader reader) { return reader.Get(s_converter); } public static void WriteUnixDateTime(this TabularWriter writer, DateTime value) { writer.Write(value, s_converter); } public static ValueTask WriteUnixDateTimeAsync(this TabularWriter writer, DateTime value, CancellationToken cancellationToken) { return writer.WriteAsync(value, s_converter, cancellationToken); } } Note Using a custom value converter in the high-level API with F# requires a custom record handler. let private converter = new UnixDateTimeConverter() let dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"') using (new TabularWriter(File.Create \"books.csv\", dialect)) (fun writer -> writer.WriteString \"Lewis Carroll\" writer.WriteString \"Alice's Adventures in Wonderland\" writer.Write (new DateTime(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc), converter) writer.FinishRecord () writer.WriteString \"H. G. Wells\" writer.WriteString \"The Time Machine\" writer.Write (new DateTime(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc), converter) writer.FinishRecord () ) using (new TabularReader(File.OpenRead \"books.csv\", dialect)) (fun reader -> while reader.TryPickRecord () do let mutable field0 = Unchecked.defaultof let mutable field1 = Unchecked.defaultof let mutable field2 = Unchecked.defaultof reader.TryReadField () |> ignore reader.TryGetString &field0 |> ignore reader.TryReadField () |> ignore reader.TryGetString &field1 |> ignore reader.TryReadField () |> ignore reader.TryGet (converter, &field2) |> ignore printfn $\"{field0} '{field1}' ({field2})\" ) Standard converters The following converters provide an option to customize the standard behavior by accepting a format specifier in the constructor: TabularDateOnlyConverter TabularDateTimeConverter TabularDateTimeOffsetConverter TabularTimeOnlyConverter" + "keywords": "Addax - Value Converters A custom converter A complete example of a custom value converter that handles System.DateTime values represented as Unix timestamps: C# F# internal class UnixDateTimeConverter : TabularConverter { public override bool TryFormat(DateTime value, Span destination, IFormatProvider? provider, out int charsWritten) { var seconds = (long)(value.ToUniversalTime() - DateTime.UnixEpoch).TotalSeconds; return seconds.TryFormat(destination, out charsWritten, \"g\", provider); } public override bool TryParse(ReadOnlySpan source, IFormatProvider? provider, out DateTime value) { if (long.TryParse(source, NumberStyles.Integer, provider, out var seconds)) { value = DateTime.UnixEpoch.AddSeconds(seconds); return true; } else { value = default; return false; } } } type internal UnixDateTimeConverter() = inherit TabularConverter() override this.TryFormat(value, destination, provider, charsWritten) = let seconds = int64 (value.ToUniversalTime () - DateTime.UnixEpoch).TotalSeconds seconds.TryFormat(destination, &charsWritten, \"g\", provider) override this.TryParse(source, provider, value) = let mutable seconds = Unchecked.defaultof if Int64.TryParse(source, NumberStyles.Integer, provider, &seconds) then value <- DateTime.UnixEpoch.AddSeconds (float seconds) true else value <- Unchecked.defaultof false High-level API (C#) Low-level API (C#) High-level API (F#) Low-level API (F#) var dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"'); using (var writer = new TabularWriter(File.Create(\"books.csv\"), dialect)) { var book1 = new Book { Author = \"Lewis Carroll\", Title = \"Alice's Adventures in Wonderland\", Published = new(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc) }; writer.WriteRecord(book1); var book2 = new Book { Author = \"H. G. Wells\", Title = \"The Time Machine\", Published = new(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc) }; writer.WriteRecord(book2); } using (var reader = new TabularReader(File.OpenRead(\"books.csv\"), dialect)) { while (reader.TryReadRecord()) { var book = reader.CurrentRecord; Console.WriteLine($\"{book.Author} '{book.Title}' ({book.Published})\"); } } [TabularRecord] internal struct Book { [TabularFieldOrder(0)] public string? Author; [TabularFieldOrder(1)] public string? Title; [TabularConverter(typeof(UnixDateTimeConverter))] [TabularFieldOrder(2)] public DateTime? Published; } using Addax.Formats.Tabular; var converter = new UnixDateTimeConverter(); var dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"'); using (var writer = new TabularWriter(File.Create(\"books.csv\"), dialect)) { writer.WriteString(\"Lewis Carroll\"); writer.WriteString(\"Alice's Adventures in Wonderland\"); writer.Write(new(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc), converter); writer.FinishRecord(); writer.WriteString(\"H. G. Wells\"); writer.WriteString(\"The Time Machine\"); writer.Write(new(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc), converter); writer.FinishRecord(); } using (var reader = new TabularReader(File.OpenRead(\"books.csv\"), dialect)) { while (reader.TryPickRecord()) { reader.TryReadField(); reader.TryGetString(out var field0); reader.TryReadField(); reader.TryGetString(out var field1); reader.TryReadField(); reader.TryGet(converter, out var field2); Console.WriteLine($\"{field0} '{field1}' ({field2})\"); } } Consider adding extension methods for using a custom value converter with the low-level API: internal static class TabularUnixDateTimeExtensions { private static readonly UnixDateTimeConverter s_converter = new(); public static bool TryGetUnixDateTime(this TabularReader reader, out DateTime value) { return reader.TryGet(s_converter, out value); } public static DateTime GetUnixDateTime(this TabularReader reader) { return reader.Get(s_converter); } public static void WriteUnixDateTime(this TabularWriter writer, DateTime value) { writer.Write(value, s_converter); } public static ValueTask WriteUnixDateTimeAsync(this TabularWriter writer, DateTime value, CancellationToken cancellationToken) { return writer.WriteAsync(value, s_converter, cancellationToken); } } Note Using a custom value converter in the high-level API with F# requires a custom record handler. let private converter = new UnixDateTimeConverter() let dialect = new TabularDialect(\"\\r\\n\", ',', '\\\"') using (new TabularWriter(File.Create \"books.csv\", dialect)) (fun writer -> writer.WriteString \"Lewis Carroll\" writer.WriteString \"Alice's Adventures in Wonderland\" writer.Write (new DateTime(1865, 11, 09, 0, 0, 0, DateTimeKind.Utc), converter) writer.FinishRecord () writer.WriteString \"H. G. Wells\" writer.WriteString \"The Time Machine\" writer.Write (new DateTime(1894, 03, 17, 0, 0, 0, DateTimeKind.Utc), converter) writer.FinishRecord () ) using (new TabularReader(File.OpenRead \"books.csv\", dialect)) (fun reader -> while reader.TryPickRecord () do let mutable field0 = Unchecked.defaultof let mutable field1 = Unchecked.defaultof let mutable field2 = Unchecked.defaultof reader.TryReadField () |> ignore reader.TryGetString &field0 |> ignore reader.TryReadField () |> ignore reader.TryGetString &field1 |> ignore reader.TryReadField () |> ignore reader.TryGet (converter, &field2) |> ignore printfn $\"{field0} '{field1}' ({field2})\" )" }, "topics/features.html": { "href": "topics/features.html", "title": "Addax - Features", - "keywords": "Addax - Features Value Types The framework has built-in support for working with tabular fields as values of the following types: Runtime Type Representation Standard System.Boolean Lexical space: \"true\" | \"false\" | \"1\" | \"0\" W3C XSD 1.1 P2 System.Byte Format specifier: \"g\" System.Char One UTF-16 code unit System.DateOnly Format: \"yyyy'-'MM'-'dd\" RFC 3339 / ISO 8601-1:2019 System.DateTime Format: \"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK\" RFC 3339 / ISO 8601-1:2019 System.DateTimeOffset Format: \"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK\" RFC 3339 / ISO 8601-1:2019 System.Decimal Format specifier: \"g\" System.Double Format specifier: \"g\" System.Guid Format: \"00000000-0000-0000-0000-000000000000\" RFC 4122 System.Half Format specifier: \"g\" System.Int16 Format specifier: \"g\" System.Int32 Format specifier: \"g\" System.Int64 Format specifier: \"g\" System.Int128 Format specifier: \"g\" System.SByte Format specifier: \"g\" System.Single Format specifier: \"g\" System.String Up to 2,147,483,591 UTF-16 code units System.TimeOnly Format: \"HH':'mm':'ss.FFFFFFF\" RFC 3339 / ISO 8601-1:2019 System.TimeSpan Format: \"[-]'P'd'DT'h'H'm'M's'.'FFFFFFF'S'\" RFC 3339 / ISO 8601-1:2019 System.UInt16 Format specifier: \"g\" System.UInt32 Format specifier: \"g\" System.UInt64 Format specifier: \"g\" System.UInt128 Format specifier: \"g\" System.Uri See Appx. A \"Collected ABNF for URI\" RFC 3986 System.Numerics.BigInteger Format specifier: \"g\" System.Byte[] Encoding: \"base16\" (\"hex\") or \"base64\" RFC 4648 Any generated record handler also supports type members of the System.Nullable type with any supported value type as the underlying type. To use a type member of the System.Byte[] type with a generated record handler, one of the available converters must be specified explicitly: TabularBase16BinaryConverter TabularBase64BinaryConverter Dialect Inferrence Note The section describes a preview feature that is available in the latest pre-release package. A dialect can be inferred from a stream based on frequency of the eligible token values: C# F# var dialect = TabularData.InferDialect(File.OpenRead(\"books.csv\"), [\"\\n\", \"\\r\\n\"], [','], ['\"']); let dialect = TabularData.InferDialect(File.OpenRead \"books.csv\", [ \"\\n\"; \"\\r\\n\" ], [ ',' ], [ '\"' ]) Performance The field and record readers can advance through tabular data without reading it completely, potentially decreasing overall processing time: C# F# public class TabularReader { public bool TrySkipField(); public ValueTask TrySkipFieldAsync(CancellationToken cancellationToken); } public class TabularReader { public bool TrySkipRecord(); public ValueTask TrySkipRecordAsync(CancellationToken cancellationToken); } type TabularReader = member TrySkipField: unit -> bool member TrySkipFieldAsync: CancellationToken -> ValueTask type TabularReader<'T> = member TrySkipRecord: unit -> bool member TrySkipRecordAsync: CancellationToken -> ValueTask Memory Usage The field reader provides access to the last read field in a way that allows reading the field without additional string allocations: C# F# public class TabularReader { public ReadOnlyMemory CurrentField { get; } } type TabularReader = member CurrentField: ReadOnlyMemory with get() The default string factory supports a mode with a thread-safe pool based on hash codes, reducing allocations when reading fields as strings: C# F# var options = new TabularOptions { StringFactory = new(maxLength: 128) }; let options = new TabularOptions ( StringFactory = new TabularStringFactory(maxLength = 128) ) References W3C - Model for Tabular Data and Metadata on the Web" + "keywords": "Addax - Features Value Types The framework has built-in support for working with tabular fields as values of the following types: Runtime Type Representation Standard System.Boolean Lexical space: \"true\" | \"false\" | \"1\" | \"0\" W3C XSD 1.1 P2 System.Byte Format specifier: \"g\" System.Char One UTF-16 code unit System.DateOnly Format: \"yyyy'-'MM'-'dd\" RFC 3339 / ISO 8601-1:2019 System.DateTime Format: \"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK\" RFC 3339 / ISO 8601-1:2019 System.DateTimeOffset Format: \"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK\" RFC 3339 / ISO 8601-1:2019 System.Decimal Format specifier: \"g\" System.Double Format specifier: \"g\" System.Guid Format: \"00000000-0000-0000-0000-000000000000\" RFC 4122 System.Half Format specifier: \"g\" System.Int16 Format specifier: \"g\" System.Int32 Format specifier: \"g\" System.Int64 Format specifier: \"g\" System.Int128 Format specifier: \"g\" System.SByte Format specifier: \"g\" System.Single Format specifier: \"g\" System.String Up to 2,147,483,591 UTF-16 code units System.TimeOnly Format: \"HH':'mm':'ss.FFFFFFF\" RFC 3339 / ISO 8601-1:2019 System.TimeSpan Format: \"[-]'P'd'DT'h'H'm'M's.FFFFFFF'S'\" RFC 3339 / ISO 8601-1:2019 System.UInt16 Format specifier: \"g\" System.UInt32 Format specifier: \"g\" System.UInt64 Format specifier: \"g\" System.UInt128 Format specifier: \"g\" System.Uri See Appx. A \"Collected ABNF for URI\" RFC 3986 System.Numerics.BigInteger Format specifier: \"g\" System.Byte[] Encoding: \"base16\" (\"hex\") or \"base64\" RFC 4648 Any generated record handler also supports type members of the System.Nullable type with any supported value type as the underlying type. To use a type member of the System.Byte[] type with a generated record handler, one of the available converters must be specified explicitly: TabularBase16BinaryConverter TabularBase64BinaryConverter Dialect Inferrence Note The section describes a preview feature that is available in the latest pre-release package. A dialect can be inferred from a stream based on frequency of the eligible token values: C# F# var dialect = TabularData.InferDialect(File.OpenRead(\"books.csv\"), [\"\\n\", \"\\r\\n\"], [','], ['\"']); let dialect = TabularData.InferDialect(File.OpenRead \"books.csv\", [ \"\\n\"; \"\\r\\n\" ], [ ',' ], [ '\"' ]) Performance The field and record readers can advance through tabular data without reading it completely, potentially decreasing overall processing time: C# F# public class TabularReader { public bool TrySkipField(); public ValueTask TrySkipFieldAsync(CancellationToken cancellationToken); } public class TabularReader { public bool TrySkipRecord(); public ValueTask TrySkipRecordAsync(CancellationToken cancellationToken); } type TabularReader = member TrySkipField: unit -> bool member TrySkipFieldAsync: CancellationToken -> ValueTask type TabularReader<'T> = member TrySkipRecord: unit -> bool member TrySkipRecordAsync: CancellationToken -> ValueTask Memory Usage The field reader provides access to the last read field in a way that allows reading the field without additional string allocations: C# F# public class TabularReader { public ReadOnlyMemory CurrentField { get; } } type TabularReader = member CurrentField: ReadOnlyMemory with get() The default string factory supports a mode with a thread-safe pool based on hash codes, reducing allocations when reading fields as strings: C# F# var options = new TabularOptions { StringFactory = new(maxLength: 128) }; let options = new TabularOptions ( StringFactory = new TabularStringFactory(maxLength = 128) ) References W3C - Model for Tabular Data and Metadata on the Web" }, "topics/grammar.html": { "href": "topics/grammar.html", diff --git a/topics/benchmarks.html b/topics/benchmarks.html index 7af0708..ebf1b1f 100644 --- a/topics/benchmarks.html +++ b/topics/benchmarks.html @@ -93,21 +93,21 @@

Addax - Benchmarks

| Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| -| 'read field: empty' | 6,738.6 μs | 6,756.1 μs | 6,609.2 μs | 6,906.1 μs | 148.40 | 389 B | -| 'read field: regular' | 17,973.0 μs | 17,939.9 μs | 17,783.3 μs | 18,286.9 μs | 55.64 | 406 B | -| 'read field: escaped' | 33,030.4 μs | 32,845.8 μs | 32,497.5 μs | 34,234.7 μs | 30.28 | 430 B | -| 'read field: empty (async)' | 7,253.0 μs | 7,235.0 μs | 7,203.0 μs | 7,328.2 μs | 137.87 | 389 B | -| 'read field: regular (async)' | 18,483.3 μs | 18,481.3 μs | 18,430.0 μs | 18,540.9 μs | 54.10 | 406 B | -| 'read field: escaped (async)' | 35,669.9 μs | 35,640.6 μs | 35,502.1 μs | 35,841.1 μs | 28.03 | 430 B | +| 'read field: empty' | 7,232.5 us | 7,256.1 us | 7,150.9 us | 7,336.2 us | 138.27 | 389 B | +| 'read field: regular' | 18,323.2 us | 18,279.8 us | 18,152.8 us | 18,554.7 us | 54.58 | 406 B | +| 'read field: escaped' | 50,433.9 us | 50,409.4 us | 50,219.8 us | 50,809.0 us | 19.83 | 447 B | +| 'read field: empty (async)' | 7,614.2 us | 7,637.3 us | 7,487.2 us | 7,747.4 us | 131.33 | 389 B | +| 'read field: regular (async)' | 19,077.0 us | 19,116.3 us | 18,918.2 us | 19,231.4 us | 52.42 | 406 B | +| 'read field: escaped (async)' | 51,548.7 us | 51,465.8 us | 51,305.2 us | 51,979.0 us | 19.40 | 395 B | | Method | Mean | Median | Min | Max | Op/s | Allocated | |------------------------------- |------------:|------------:|------------:|------------:|-------:|----------:| -| 'write field: empty' | 5,341.3 μs | 5,352.1 μs | 5,256.9 μs | 5,423.7 μs | 187.22 | 277 B | -| 'write field: regular' | 9,236.5 μs | 9,238.9 μs | 9,157.1 μs | 9,351.6 μs | 108.27 | 395 B | -| 'write field: escaped' | 14,607.3 μs | 14,603.4 μs | 14,588.9 μs | 14,633.8 μs | 68.46 | 395 B | -| 'write field: empty (async)' | 10,284.7 μs | 10,270.8 μs | 10,175.8 μs | 10,418.4 μs | 97.23 | 283 B | -| 'write field: regular (async)' | 14,646.5 μs | 14,634.4 μs | 14,588.9 μs | 14,711.1 μs | 68.28 | 385 B | -| 'write field: escaped (async)' | 20,475.2 μs | 20,501.8 μs | 20,289.4 μs | 20,557.1 μs | 48.84 | 406 B | +| 'write field: empty' | 5,401.2 us | 5,387.5 us | 5,325.0 us | 5,523.5 us | 185.15 | 389 B | +| 'write field: regular' | 10,059.8 us | 10,060.6 us | 10,031.1 us | 10,101.1 us | 99.41 | 385 B | +| 'write field: escaped' | 14,677.5 us | 14,675.2 us | 14,640.0 us | 14,733.7 us | 68.13 | 395 B | +| 'write field: empty (async)' | 10,243.5 us | 10,240.5 us | 10,199.4 us | 10,303.8 us | 97.62 | 395 B | +| 'write field: regular (async)' | 15,227.2 us | 15,232.5 us | 15,163.4 us | 15,290.2 us | 65.67 | 395 B | +| 'write field: escaped (async)' | 19,948.4 us | 19,946.0 us | 19,895.2 us | 19,998.9 us | 50.13 | 406 B | Mean : Arithmetic mean of all measurements Error : Half of 99.9% confidence interval diff --git a/topics/extensibility/value-converters.html b/topics/extensibility/value-converters.html index d1aff55..c468ac6 100644 --- a/topics/extensibility/value-converters.html +++ b/topics/extensibility/value-converters.html @@ -321,17 +321,6 @@
Note
-

-

Standard converters

-

-

The following converters provide an option to customize the standard behavior by accepting a format specifier in the constructor:

-

- diff --git a/topics/features.html b/topics/features.html index ca6ecc5..4bc9fea 100644 --- a/topics/features.html +++ b/topics/features.html @@ -192,7 +192,7 @@

Value Types

System.TimeSpan -Format: "[-]'P'd'DT'h'H'm'M's'.'FFFFFFF'S'" +Format: "[-]'P'd'DT'h'H'm'M's.FFFFFFF'S'" RFC 3339 / ISO 8601-1:2019