digitalmars.D - Appender and CTFE
- Trass3r (3/3) Mar 03 2011 replace() doesn't work in CTFE anymore cause it was modified to be based...
- bearophile (4/5) Mar 03 2011 There's no need for this, there is __ctfe (that thanks to fixing bug 417...
- dennis luehring (4/7) Mar 03 2011 but doesn't that kill a little bit the ctfe feature :) ... if i always
- Jacob Carlborg (5/10) Mar 03 2011 So much for the "having the same implementation for the compile time
- Steven Schveighoffer (9/23) Mar 03 2011 Actually, I think even if Appender wasn't implemented via pImpl style, i...
- Jacob Carlborg (5/30) Mar 03 2011 Yeah, but Walter and/or Andrei has mentioned that as a feature. Having
- Andrei Alexandrescu (6/38) Mar 03 2011 I see nothing wrong with the occasional forking conditioned by __ctfe.
- Kevin Bealer (7/12) Mar 04 2011 Regarding maintenance burden, it should be easy to test the correctness ...
- dennis luehring (9/22) Mar 04 2011 based on the complexity of the "function" is can be much much more then
- David Nadlinger (7/9) Mar 03 2011 Well, that's exactly what __ctfe allows for in this case – optimizing ...
- Steven Schveighoffer (6/11) Mar 03 2011 Yes, it is something I intend to do. I want to make an (un@safe) scoped...
- Andrei Alexandrescu (5/17) Mar 03 2011 One broader question would be if Appender's optimization is still needed...
- Steven Schveighoffer (7/27) Mar 03 2011 It is large. The Appender struct keeps track of its capacity in a local...
- Steven Schveighoffer (4/5) Mar 03 2011 code attached if anyone is interested.
- Steven Schveighoffer (6/10) Mar 03 2011 err... you can comment out the assert and sanity check at the end. It
- spir (10/30) Mar 03 2011 When I tried to use Appender, it was actually slightly slower than plain...
- Steven Schveighoffer (4/32) Mar 03 2011 I believe those problems have been resolved. It was fixed in the latest...
- kenji hara (9/31) Mar 03 2011 Even without performance issue, Appender is necessary because it
- Andrei Alexandrescu (3/11) Mar 03 2011 Agreed. I was mostly hoping about implementation simplification.
- Steven Schveighoffer (10/17) Mar 03 2011 Performance really is the only issue, the complexity of Appender is not ...
- kenji hara (5/24) Mar 03 2011 I'm sorry my point was irrelevant.
replace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?
Mar 03 2011
Trass3r:I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime. Bye, bearophile
Mar 03 2011
Am 03.03.2011 14:12, schrieb bearophile:Trass3r:but doesn't that kill a little bit the ctfe feature :) ... if i always pushed to the direct of using another branch, im also push to have another branch of errors :) - whats the point of ctfe then?I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime.
Mar 03 2011
On 2011-03-03 14:12, bearophile wrote:Trass3r:So much for the "having the same implementation for the compile time function and the runtime function". -- /Jacob CarlborgI think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime. Bye, bearophile
Mar 03 2011
On Thu, 03 Mar 2011 10:28:00 -0500, Jacob Carlborg <doob me.com> wrote:On 2011-03-03 14:12, bearophile wrote:Actually, I think even if Appender wasn't implemented via pImpl style, it wouldn't be available to CTFE because it uses implementation details from the GC and runtime (for performance). I think a __ctfe thing is probably the right thing to do. Note that nobody cares about append performance in CTFE because it only affects compile time, not runtime, so the CTFE version can be really foolish and simple, and nobody cares if it's "implemented the same". -SteveTrass3r:So much for the "having the same implementation for the compile time function and the runtime function".I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime. Bye, bearophile
Mar 03 2011
On 2011-03-03 16:35, Steven Schveighoffer wrote:On Thu, 03 Mar 2011 10:28:00 -0500, Jacob Carlborg <doob me.com> wrote:Yeah, but Walter and/or Andrei has mentioned that as a feature. Having the same code for compile time and runtime. -- /Jacob CarlborgOn 2011-03-03 14:12, bearophile wrote:Actually, I think even if Appender wasn't implemented via pImpl style, it wouldn't be available to CTFE because it uses implementation details from the GC and runtime (for performance). I think a __ctfe thing is probably the right thing to do. Note that nobody cares about append performance in CTFE because it only affects compile time, not runtime, so the CTFE version can be really foolish and simple, and nobody cares if it's "implemented the same". -SteveTrass3r:So much for the "having the same implementation for the compile time function and the runtime function".I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime. Bye, bearophile
Mar 03 2011
On 3/3/11 10:05 AM, Jacob Carlborg wrote:On 2011-03-03 16:35, Steven Schveighoffer wrote:I see nothing wrong with the occasional forking conditioned by __ctfe. Even today, code may fork an optimized but nonportable implementation of some algorithm. The main requirement is that such forks are rare enough to not cause undue maintenance burden. AndreiOn Thu, 03 Mar 2011 10:28:00 -0500, Jacob Carlborg <doob me.com> wrote:Yeah, but Walter and/or Andrei has mentioned that as a feature. Having the same code for compile time and runtime.On 2011-03-03 14:12, bearophile wrote:Actually, I think even if Appender wasn't implemented via pImpl style, it wouldn't be available to CTFE because it uses implementation details from the GC and runtime (for performance). I think a __ctfe thing is probably the right thing to do. Note that nobody cares about append performance in CTFE because it only affects compile time, not runtime, so the CTFE version can be really foolish and simple, and nobody cares if it's "implemented the same". -SteveTrass3r:So much for the "having the same implementation for the compile time function and the runtime function".I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?There's no need for this, there is __ctfe (that thanks to fixing bug 4177 is usable in pure functions too), that allows to create two paths inside the Appender, one for CT and one for runtime. Bye, bearophile
Mar 03 2011
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleI see nothing wrong with the occasional forking conditioned by __ctfe. Even today, code may fork an optimized but nonportable implementation of some algorithm. The main requirement is that such forks are rare enough to not cause undue maintenance burden. AndreiRegarding maintenance burden, it should be easy to test the correctness of such code: in a unit test: enum a = f(...); assert(a == f(...)); Kevin
Mar 04 2011
Am 04.03.2011 09:51, schrieb Kevin Bealer:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articlebased on the complexity of the "function" is can be much much more then that... and the problem is that "normal" users tend to forget unit-tests... the _ctfe thing is great because it solves problems in the real world still better then before, but it easily opens the door to multi-branch development with many different error-szenarios the question is: is there a way to keep the _ctfe-branching under control - i think as long as the ctfe functionality is very near to the normal function world it will kept low by natureI see nothing wrong with the occasional forking conditioned by __ctfe. Even today, code may fork an optimized but nonportable implementation of some algorithm. The main requirement is that such forks are rare enough to not cause undue maintenance burden. AndreiRegarding maintenance burden, it should be easy to test the correctness of such code: in a unit test: enum a = f(...); assert(a == f(...)); Kevin
Mar 04 2011
On 3/3/11 4:28 PM, Jacob Carlborg wrote:So much for the "having the same implementation for the compile time function and the runtime function".Well, that's exactly what __ctfe allows for in this case – optimizing a small section of the code for performance using runtime-only stuff, while still being able to call all functions depending of it at compile time too… Do you think you will find time to work on this reasonably soon, Steve? David
Mar 03 2011
On Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:replace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
On 3/3/11 8:34 AM, Steven Schveighoffer wrote:On Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:One broader question would be if Appender's optimization is still needed after Steve's improvements to ~=. What is the current performance gap between using ~= and Appender? Andreireplace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
On Thu, 03 Mar 2011 11:03:31 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/3/11 8:34 AM, Steven Schveighoffer wrote:It is large. The Appender struct keeps track of its capacity in a local member, instead of having to look it up using the GC. The lookup cache helps, but it's still a convoluted lookup, vs a simple member dereference. Using trivial benchmarks, I found Appender is about 5x faster than ~=. -SteveOn Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:One broader question would be if Appender's optimization is still needed after Steve's improvements to ~=. What is the current performance gap between using ~= and Appender?replace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
On Thu, 03 Mar 2011 11:19:12 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:Using trivial benchmarks, I found Appender is about 5x faster than ~=.code attached if anyone is interested. -Steve
Mar 03 2011
On Thu, 03 Mar 2011 11:20:44 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Thu, 03 Mar 2011 11:19:12 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:err... you can comment out the assert and sanity check at the end. It doesn't add significant time to the runtime, but I was testing my fixes for bug 5198. -SteveUsing trivial benchmarks, I found Appender is about 5x faster than ~=.code attached if anyone is interested.
Mar 03 2011
On 03/03/2011 05:03 PM, Andrei Alexandrescu wrote:On 3/3/11 8:34 AM, Steven Schveighoffer wrote:When I tried to use Appender, it was actually slightly slower than plain ~=. The reason was, IIRC, Appender is only efficient when bits added are simple elements, not mini-arrays to be concatenated (there was a thread about that). There was also an issue with reserve. Denis -- _________________ vita es estrany spir.wikidot.comOn Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:One broader question would be if Appender's optimization is still needed after Steve's improvements to ~=. What is the current performance gap between using ~= and Appender?replace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
On Thu, 03 Mar 2011 11:22:00 -0500, spir <denis.spir gmail.com> wrote:On 03/03/2011 05:03 PM, Andrei Alexandrescu wrote:I believe those problems have been resolved. It was fixed in the latest release (2.052) -SteveOn 3/3/11 8:34 AM, Steven Schveighoffer wrote:When I tried to use Appender, it was actually slightly slower than plain ~=. The reason was, IIRC, Appender is only efficient when bits added are simple elements, not mini-arrays to be concatenated (there was a thread about that). There was also an issue with reserve.On Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:One broader question would be if Appender's optimization is still needed after Steve's improvements to ~=. What is the current performance gap between using ~= and Appender?replace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
Even without performance issue, Appender is necessary because it configures output range. Currently std.array.put does not allow empty array as its argument. int[] arr = []; arr.put(1); // invalid. this does not means appending. Therefore building an array its length is not known beforehand requires Appender. Kenji 2011/3/4 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:On 3/3/11 8:34 AM, Steven Schveighoffer wrote:On Thu, 03 Mar 2011 07:41:49 -0500, Trass3r <un known.com> wrote:One broader question would be if Appender's optimization is still needed after Steve's improvements to ~=. What is the current performance gap between using ~= and Appender? Andreireplace() doesn't work in CTFE anymore cause it was modified to be based on Appender. According to klickverbot, other phobos functions share that fate. I think something should be done about this. Couldn't Appender be implemented without using a pointer to a struct?Yes, it is something I intend to do. I want to make an (un safe) scoped appender which does not use a pImpl, along with a safe appender which does use pImpl. It should be as easy as making the impl struct a public struct. -Steve
Mar 03 2011
On 3/3/11 10:54 AM, kenji hara wrote:Even without performance issue, Appender is necessary because it configures output range. Currently std.array.put does not allow empty array as its argument. int[] arr = []; arr.put(1); // invalid. this does not means appending. Therefore building an array its length is not known beforehand requires Appender. KenjiAgreed. I was mostly hoping about implementation simplification. Andrei
Mar 03 2011
On Thu, 03 Mar 2011 11:54:58 -0500, kenji hara <k.hara.pg gmail.com> wrote:Even without performance issue, Appender is necessary because it configures output range. Currently std.array.put does not allow empty array as its argument. int[] arr = []; arr.put(1); // invalid. this does not means appending. Therefore building an array its length is not known beforehand requires Appender.Performance really is the only issue, the complexity of Appender is not necessary for your issue. One could make a very simple appender struct if creating a proper output range was the only problem: struct appender(T) { T[] data; void put(T t) { data ~= t; } } -Steve
Mar 03 2011
I'm sorry my point was irrelevant. Kenji 2011/3/4 Steven Schveighoffer <schveiguy yahoo.com>:On Thu, 03 Mar 2011 11:54:58 -0500, kenji hara <k.hara.pg gmail.com> wrot=e:ifEven without performance issue, Appender is necessary because it configures output range. Currently std.array.put does not allow empty array as its argument. int[] arr =3D []; arr.put(1); =A0// invalid. this does not means appending. Therefore building an array its length is not known beforehand requires Appender.Performance really is the only issue, the complexity of Appender is not necessary for your issue. =A0One could make a very simple appender struct=creating a proper output range was the only problem: struct appender(T) { =A0 T[] data; =A0 void put(T t) { data ~=3D t; } } -Steve
Mar 03 2011