View Ticket
Not logged in
Ticket UUID: f199b0fd298ae0efe449df9f149a96c17898e352
Title: Suggest that SQLiteDataReaderValue should be a union
Status: Deferred Type: Performance
Severity: Important Priority: Medium
Subsystem: Data_Reader Resolution: Under_Review
Last Modified: 2016-10-10 20:14:22
Version Found In:
User Comments:
anonymous added on 2016-10-09 21:39:53:
As far as I can tell, only 1 field of this class is ever used for any given instance. Since every field is an object reference, and assuming 16 bytes per, this should mean around a 1400% savings in memory per instance.

mistachkin added on 2016-10-10 05:16:47:
A couple observations:

1. The C# language does not support unions in the same way as C/C++.  It
   is possible to create a union-like type; however, it makes the code
   more difficult to maintain.

2. Currently, the SQLiteDataReaderValue class is only used (by the
   SQLiteDataReader class) when read-value callbacks are enabled for the
   connection, which is not enabled by default.

3. Only one instance per-thread of the SQLiteDataReaderValue class is
   created at a time -AND- that instance of discarded soon after the
   callback returns.

anonymous (claiming to be added on 2016-10-10 20:14:22:
Yes, it seems that this functionality would be most useful in testing or tracing scenarios. However, even though only 1 instance is created at a time, it is created for each call to Get(somevalue); which, if fired for each column  in a 20-column table over several hundred rows, is a lot of allocation. Granted, they are short-lived, and will be promptly collected on the next Gen0 sweep. But that sweep will have to come a lot sooner than it would with a smaller data structure.

The union that I am using in my fork sets all of the Nullable<T>'s at offset 0, and all of the object refs at offset 24 (for proper alignment on 32- or 64-bit systems.) I realize that Nullable<T>'s are structs, not object refs, but I tend to think of them that way because of the nullity involved.

It's not as compact as it should be, because the C# compiler apparently can't tell that if everything is at offset 0, it doesn't matter if one is an object ref or not.