From 4fa671952895b39a08d8ea1140e96814175f2cc7 Mon Sep 17 00:00:00 2001 From: Curt Hagenlocher Date: Fri, 18 Aug 2023 11:55:30 -0700 Subject: [PATCH] GH-36816: [C#] Reduce allocations (#36817) ### What changes are included in this PR? A small refactoring to make a small improvement in memory utilization. ### Are these changes tested? Existing test coverage should be sufficient. * Closes: #36816 Authored-by: Curt Hagenlocher Signed-off-by: David Li --- csharp/src/Apache.Arrow/Arrays/Time32Array.cs | 2 +- csharp/src/Apache.Arrow/Arrays/Time64Array.cs | 2 +- .../Apache.Arrow/C/CArrowArrayStreamExporter.cs | 4 ++-- csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs | 14 +++++++------- csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs | 6 +++--- csharp/src/Apache.Arrow/Types/IntervalUnit.cs | 11 ++++++++++- csharp/src/Apache.Arrow/Types/Time32Type.cs | 2 +- csharp/src/Apache.Arrow/Types/Time64Type.cs | 2 +- csharp/src/Apache.Arrow/Types/TimeType.cs | 11 +++++++++++ 9 files changed, 37 insertions(+), 17 deletions(-) diff --git a/csharp/src/Apache.Arrow/Arrays/Time32Array.cs b/csharp/src/Apache.Arrow/Arrays/Time32Array.cs index 31d17d06a1e40..824694cd6d04b 100644 --- a/csharp/src/Apache.Arrow/Arrays/Time32Array.cs +++ b/csharp/src/Apache.Arrow/Arrays/Time32Array.cs @@ -46,7 +46,7 @@ public Builder() : this(Time32Type.Default) { } public Builder(TimeUnit unit) - : this(new Time32Type(unit)) { } + : this((Time32Type)TimeType.FromTimeUnit(unit)) { } /// /// Construct a new instance of the class. diff --git a/csharp/src/Apache.Arrow/Arrays/Time64Array.cs b/csharp/src/Apache.Arrow/Arrays/Time64Array.cs index 95faf18fe9e61..9fc2ae4be1563 100644 --- a/csharp/src/Apache.Arrow/Arrays/Time64Array.cs +++ b/csharp/src/Apache.Arrow/Arrays/Time64Array.cs @@ -49,7 +49,7 @@ public Builder() : this(Time64Type.Default) { } public Builder(TimeUnit unit) - : this(new Time64Type(unit)) { } + : this((Time64Type)TimeType.FromTimeUnit(unit)) { } /// /// Construct a new instance of the class. diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs b/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs index 0a0f1cc837459..17b320f869406 100644 --- a/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs +++ b/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs @@ -61,9 +61,9 @@ public static unsafe void ExportArrayStream(IArrowArrayStream arrayStream, CArro { throw new ArgumentNullException(nameof(arrayStream)); } - if (arrayStream == null) + if (cArrayStream == null) { - throw new ArgumentNullException(nameof(arrayStream)); + throw new ArgumentNullException(nameof(cArrayStream)); } cArrayStream->private_data = ExportedArrayStream.Export(arrayStream); diff --git a/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs b/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs index b21f24edba9af..ec613d59d2cb9 100644 --- a/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs +++ b/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs @@ -268,14 +268,14 @@ public ArrowType GetAsType() // Date and time "tdD" => Date32Type.Default, "tdm" => Date64Type.Default, - "tts" => new Time32Type(TimeUnit.Second), - "ttm" => new Time32Type(TimeUnit.Millisecond), - "ttu" => new Time64Type(TimeUnit.Microsecond), - "ttn" => new Time64Type(TimeUnit.Nanosecond), + "tts" => TimeType.Second, + "ttm" => TimeType.Millisecond, + "ttu" => TimeType.Microsecond, + "ttn" => TimeType.Nanosecond, // TODO: duration not yet implemented - "tiM" => new IntervalType(IntervalUnit.YearMonth), - "tiD" => new IntervalType(IntervalUnit.DayTime), - //"tin" => new IntervalType(IntervalUnit.MonthDayNanosecond), // Not yet implemented + "tiM" => IntervalType.YearMonth, + "tiD" => IntervalType.DayTime, + //"tin" => IntervalType.MonthDayNanosecond, // Not yet implemented _ => throw new NotSupportedException("Data type is not yet supported in import.") }; } diff --git a/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs b/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs index 7426ba4e86959..f5031fbfb56a4 100644 --- a/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs +++ b/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs @@ -165,9 +165,9 @@ private static Types.IArrowType GetFieldArrowType(Flatbuf.Field field, Field[] c switch (timeMeta.BitWidth) { case 32: - return new Types.Time32Type(timeMeta.Unit.ToArrow()); + return (Time32Type)TimeType.FromTimeUnit(timeMeta.Unit.ToArrow()); case 64: - return new Types.Time64Type(timeMeta.Unit.ToArrow()); + return (Time64Type)TimeType.FromTimeUnit(timeMeta.Unit.ToArrow()); default: throw new InvalidDataException("Unsupported time bit width"); } @@ -178,7 +178,7 @@ private static Types.IArrowType GetFieldArrowType(Flatbuf.Field field, Field[] c return new Types.TimestampType(unit, timezone); case Flatbuf.Type.Interval: Flatbuf.Interval intervalMetadata = field.Type().Value; - return new Types.IntervalType(intervalMetadata.Unit.ToArrow()); + return Types.IntervalType.FromIntervalUnit(intervalMetadata.Unit.ToArrow()); case Flatbuf.Type.Utf8: return Types.StringType.Default; case Flatbuf.Type.FixedSizeBinary: diff --git a/csharp/src/Apache.Arrow/Types/IntervalUnit.cs b/csharp/src/Apache.Arrow/Types/IntervalUnit.cs index 6dda0cfe94b78..bcd67e112dd2c 100644 --- a/csharp/src/Apache.Arrow/Types/IntervalUnit.cs +++ b/csharp/src/Apache.Arrow/Types/IntervalUnit.cs @@ -19,11 +19,15 @@ namespace Apache.Arrow.Types public enum IntervalUnit { YearMonth = 0, - DayTime = 1 + DayTime = 1, } public sealed class IntervalType : FixedWidthType { + public static readonly IntervalType YearMonth = new IntervalType(IntervalUnit.YearMonth); + public static readonly IntervalType DayTime = new IntervalType(IntervalUnit.DayTime); + private static readonly IntervalType[] _types = new IntervalType[] { YearMonth, DayTime }; + public override ArrowTypeId TypeId => ArrowTypeId.Interval; public override string Name => "date"; public override int BitWidth => 64; @@ -36,5 +40,10 @@ public IntervalType(IntervalUnit unit = IntervalUnit.YearMonth) } public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor); + + public static IntervalType FromIntervalUnit(IntervalUnit unit) + { + return _types[(int)unit]; + } } } diff --git a/csharp/src/Apache.Arrow/Types/Time32Type.cs b/csharp/src/Apache.Arrow/Types/Time32Type.cs index 99c409babdb26..80a23d49344ae 100644 --- a/csharp/src/Apache.Arrow/Types/Time32Type.cs +++ b/csharp/src/Apache.Arrow/Types/Time32Type.cs @@ -18,7 +18,7 @@ namespace Apache.Arrow.Types { public sealed class Time32Type : TimeType { - public static readonly Time32Type Default = new Time32Type(); + public static readonly Time32Type Default = Millisecond; public override ArrowTypeId TypeId => ArrowTypeId.Time32; public override string Name => "time32"; diff --git a/csharp/src/Apache.Arrow/Types/Time64Type.cs b/csharp/src/Apache.Arrow/Types/Time64Type.cs index 2777deb228ed8..e7d911c2772b4 100644 --- a/csharp/src/Apache.Arrow/Types/Time64Type.cs +++ b/csharp/src/Apache.Arrow/Types/Time64Type.cs @@ -18,7 +18,7 @@ namespace Apache.Arrow.Types { public sealed class Time64Type : TimeType { - public static readonly Time64Type Default = new Time64Type(); + public static readonly Time64Type Default = Nanosecond; public override ArrowTypeId TypeId => ArrowTypeId.Time64; public override string Name => "time64"; diff --git a/csharp/src/Apache.Arrow/Types/TimeType.cs b/csharp/src/Apache.Arrow/Types/TimeType.cs index 9afa3fb62cdc7..48c7fdb5f1bea 100644 --- a/csharp/src/Apache.Arrow/Types/TimeType.cs +++ b/csharp/src/Apache.Arrow/Types/TimeType.cs @@ -26,11 +26,22 @@ public enum TimeUnit public abstract class TimeType: FixedWidthType { + public static readonly Time32Type Second = new Time32Type(TimeUnit.Second); + public static readonly Time32Type Millisecond = new Time32Type(TimeUnit.Millisecond); + public static readonly Time64Type Microsecond = new Time64Type(TimeUnit.Microsecond); + public static readonly Time64Type Nanosecond = new Time64Type(TimeUnit.Nanosecond); + private static readonly TimeType[] _types = new TimeType[] { Second, Millisecond, Microsecond, Nanosecond }; + public TimeUnit Unit { get; } protected TimeType(TimeUnit unit) { Unit = unit; } + + public static TimeType FromTimeUnit(TimeUnit unit) + { + return _types[(int)unit]; + } } }