On May 2, 2013, at 5:35 PM, Anurag Kalia
Rob Stewart-6 wrote
On May 1, 2013, at 4:33 PM, Anurag Kalia wrote:
Optimizing I/O, which is a relatively slow process anyway, is possibly misguided. The YMD format could be extracted from the serial format to reuse, but I imagine a given object being formatted for I/O in a single function call, à la strftime(), rather than in a series of formatting calls. Still, even the latter is possible with a formatter object which extracts the YMD values once and applies various formatting operations, as desired.
So, you are trying to say that optimizing I/O is not really rewarding since I/O by itself is already orders of magnitude slower? It makes sense to me.
Yes
But might there not be cases where we have to store the output not to some output device, but to a string in memory only?
I don't imagine there would be much call for doing formatted output of many strings to a buffer. Even then, each date of interest must be cast into the I/O friendly form, so there's no room for optimizing that case, is there?
For the vast majority however, serial representation is good enough. After caching as you know, performance nears ymd in these scenarios too.
Caching suggests larger objects and, possibly lower locality of reference.
By caching, I meant to say retrieve y,m,d values explicitly as well as some other properties of the date.
That sounds like conversion to another date type.
I myself have dropped this constructor. After all, it is not difficult for users to check documentation for the order of the date parameters. It just eats up the performance anyway, even if it is just a switch statement.
I'm not sure of the context here, but relying on documentation to ensure correct argument order will only frustrate users, because it is error prone. The Named Constructor Idiom is beneficial in such cases.
To recap, the constructor under discussion looks like:
date(int a, int b, int c, date_format fmt);
where date_format is an enum type:
enum date_format { ymd, dmy, mdy };
so that following construction is possible:
date dt = date(2013, 6, 5, ymd);
All information required is directly in front of the eyes. But thinking more about it, y-m-d should be the only case possible in the constructor.
I comment on this further down, but that does address the documentation dependency problem.
It is because date object is streamable. Thus, such construction is possible:
std::cout << date(4, 5, 2013, dmy);
where output comes out to be "2013-05-04". This seems a little clumsy to me.
If there is I/O support, I'd hope for other formats. Regardless, those in different regions will want the arguments ordered in their locale's order. You could require them in magnitude order -- YMD -- but that's less friendly and isn't checked by the compiler.
That is the only reason I am antagonist to otherwise completely natural construction of:
date natural = day(7) / month(12) / year(2013);
That will be harder to optimize. I'm not saying that it wouldn't be optimized, just harder, so less likely. It's also unlike anything in the standard. I don't think that's any clearer than this: date d(7, dec, year(2013)) (The months can be from an enumerated type.) One can specify a day or year object and avoid ambiguity: date(unsigned, month, year); date(day, month, unsigned); You can even handle other orders that way: date(month, unsigned, year); date(month, day, unsigned); date(unsigned, day, month); date(year, unsigned, month); One can also be explicit for both day and year: date(year, month, day); date(month, day, year); date(day, month, year); date(day, year, month); (That last seems particularly odd, but could be supported.) I'm assuming explicit constructors for day and year, of course.
Now, back to your named constructor idiom. Thanks! How true that you learn something new everyday! I liked it. It actually seems very suitable to my date class since we are constructing dates also in ordinal date notation (year, day_of_year) as well as week date notation (year, week_no, weekday).
Again, I have doubts still. First that I have never encountered it in standard library till now - the library that I use the most. If it exists somewhere in it or Boost, that would hearten me.
make_pair, make_shared are something like it. However, the reason you've not seen it used is that no standardized type has needed it.
Moreover, named constructor idiom allows construction of objects by the objects themselves. It has possibility to look ugly. Though, as I write, I think one could always make them first-class functions which are friends of date class.
date::ymd(2013, 5, 3) make_ymd(2013, 5, 3) I don't think this is right, though: ymd(2013, 5, 3)
Is the latter ok approach? My concerns also extend to performance of resulting code. But people on internet say that the call is almost always optimized away.
RVO should take care of things. ___ Rob (Sent from my portable computation engine)