Re: No implicitly convert derived ptr to base ptr?
On 04/25/2012 07:50 AM, Nick Sabalausky wrote: The compiler rejects this: class Base {} class Derived : Base {} void main() { Base*basePtr; Derived* derivedPtr; basePtr = derivedPtr; // ERROR } Is that really correct that it shouldn't be allowed? Yes it is. It was allowed a number of releases ago, but that bug has since been fixed. Example that shows unsoundness: class Base {} class Derived1 : Base {} class Derived2 : Base {} void main() { Derived1 d1; Base* basePtr = &d1; *basePtr = new Derived2; assert(typeid(d1)==typeid(Derived2) && !is(Derived2: typeof(d1)); } Note that the conversion succeeds if the tail of the pointer is not mutable, eg Derived* implicitly converts to const(Base)*.
Re: No implicitly convert derived ptr to base ptr?
On Wednesday, April 25, 2012 01:50:51 Nick Sabalausky wrote: > The compiler rejects this: > > class Base {} > class Derived : Base {} > > void main() > { > Base*basePtr; > Derived* derivedPtr; > > basePtr = derivedPtr; // ERROR > } > > Is that really correct that it shouldn't be allowed? Well, given that pointers aren't polymorphic at all, it's not all that great an idea in general to assign a derived class object to a base class pointer, so it's arguably a good thing that it doesn't work, but I am a bit surprised that it doesn't work. - Jonathan M Davis
No implicitly convert derived ptr to base ptr?
The compiler rejects this: class Base {} class Derived : Base {} void main() { Base*basePtr; Derived* derivedPtr; basePtr = derivedPtr; // ERROR } Is that really correct that it shouldn't be allowed?
Re: Extending std.format.formattedRead
H. S. Teoh: What's the correct way of implementing formattedRead support for user-defined types? I tried overloading the unformatValue() template, but for some reason the compiler doesn't seem to be picking it up. Maybe do you want to open this discussion in the main D newsgroup? I think this is not a very important issue, but it's a nice thing to have. Bye, bearophile
Re: Extending std.format.formattedRead
On Wed, Apr 25, 2012 at 03:42:25AM +0200, Kenji Hara wrote: > On Tuesday, 24 April 2012 at 21:50:03 UTC, H. S. Teoh wrote: > >What's the correct way of implementing formattedRead support for > >user-defined types? I tried overloading the unformatValue() > >template, > >but for some reason the compiler doesn't seem to be picking it up. > > Unfortunately, there is not yet general way. > The definition of unformatValue for user-defined type in different > module isn't considered by std.format module. D's module system is > closed in basic. [...] Does it make sense to add a fromString() method to user-defined types for this? D's toString support is awesome (you can basically call to!string on just about anything and it works). It would be nice to have similar support for the reverse operation. T -- "Life is all a great joke, but only the brave ever get the point." -- Kenneth Rexroth
Re: Extending std.format.formattedRead
On Tuesday, 24 April 2012 at 21:50:03 UTC, H. S. Teoh wrote: What's the correct way of implementing formattedRead support for user-defined types? I tried overloading the unformatValue() template, but for some reason the compiler doesn't seem to be picking it up. Unfortunately, there is not yet general way. The definition of unformatValue for user-defined type in different module isn't considered by std.format module. D's module system is closed in basic. Kenji Hara
Re: Range of random numbers
On 24/04/12 13:50, Christophe wrote: We could also use a template to make a range out of a delegate and avoid this workarround... What I'd _really_ like to see is something which would allow you to generate a range of random numbers with an expression like, auto rr = randomRange!distribution(/* distribution parameters */); or, auto rr = randomRange!distribution(size_t n, /* distribution parameters */); ... which would generate you either an infinite or length-n range of random numbers generated by the specified distribution, with the passed parameters. So, you could call e.g., auto rr = randomRange!(uniform!"()")(100, 0.0, 1.0); auto rr = randomRange!pareto(100, alpha, sigma); auto rr = randomRange!exponential(lambda); ... etc. But I'm not sure if this is feasible.
Re: D 50% slower than C++. What I'm doing wrong?
Marco Leise: I ported fast paq8 (fp8) to D, and with some careful D-ification and optimization it runs a bit faster than the original C program when compiled with the GCC on Linux x86_64, Core 2 Duo. I guess you mean GDC. With DMD, even if you are a good D programmer, it's not easy to beat that original C compressor :-) Do you have a link to your D version? Matt Mahoney is probably willing to put a link in his site to your D version. I don't know about this version of paq you ported the coder from, It was a very basic coder. The D GC on the other hand allocates that memory and writes zeroes to it immediately. Is this always done the first time the memory is allocated by the GC? The effect is two fold: First, the calloc version will use much less RAM, if the 'allocated' buffers aren't fully used (e.g. you compressed a small file). On the other hand in D you may allocate the memory in a more conscious way. "static assert(Foo.sizeof == 64);" helped me find a bug there that resulted from switching from C bitfields to the D version (which is a library solution in Phobos). The Phobos D bitfields aren't required to mimic C, but that's an interesting case. Maybe it's a difference interesting to be taken a look at. Do you have the code of the two C-D versions? Bye, bearophile
Extending std.format.formattedRead
What's the correct way of implementing formattedRead support for user-defined types? I tried overloading the unformatValue() template, but for some reason the compiler doesn't seem to be picking it up. T -- People walk. Computers run.
Re: Object Serialization?
On 04/24/2012 08:50 PM, Jacob Carlborg wrote: On 2012-04-24 18:42, dcoder wrote: Hello. I'm probably not looking hard enough, but Do we have any standard d-library for serializing an object/object tree into -for example- an xml file? thanks. You can have a look at Orange: https://github.com/jacob-carlborg/orange Tutorials: http://dsource.org/projects/orange/wiki/Tutorials API reference: http://dl.dropbox.com/u/18386187/orange_docs/orange.serialization.Serializer.html Does it automatically pick everything to serialize? How would you make it more selective? struct Me { int x; int y; } serialize x but not y. Would you have to create a custom serializer? If so I would like to see an example with the custom serializer and deserializer that only does the x. Basic Example Serialize Through Base Class Register Serializer? There is no register serializer example. 277 private void serializeStruct (T) (T value, string key, Id id) 278 { 279 string type = T.stringof; 280 281 triggerEvents(serializing, value, { 282 archive.archiveStruct(type, key, id, { 283 if (type in serializers) 284 { 285 auto wrapper = getSerializerWrapper!(T)(type); 286 wrapper(value, this, key); 287 } 288 289 else 290 { 291 static if (isSerializable!(T)) 292 value.toData(this, key); 293 294 else 295 objectStructSerializeHelper(value); 296 } 297 }); 298 }); 299 } I assume that the wrapper is the custom serializer that can be registered. Then there is the toData that a struct can have, basically member functions that do the serialization. Priority is given to the registered serializer over the member functions. And the last one. ObjectStructSerializerHelper is more a default serializer if none is registered or doesn't have the correct isSerializable member functions. ObjectStructSerializerHelper(T) (T .) Just browsing, I haven't downloaded anything.
Re: avoid toLower in std.algorithm.sort compare alias
On Tuesday, April 24, 2012 12:24:44 Regan Heath wrote: > On Mon, 23 Apr 2012 16:43:20 +0100, Steven Schveighoffer > > wrote: > > While dealing with unicode in my std.stream rewrite, I've found that > > hand-decoding dchars is way faster than using library calls. > > After watching Andrei's talk on generic and generative programming I have > to ask, which routines are you avoiding .. it seems we need to make them > as good as the hand coded code you've written... In general, when operating on strings generically, you up having to treat them as ranges of dchar and decode everything, but there are a lot of cases where you can special-case algorithms for narrow strings and avoid decoding them. Phobos does this a lot (though it can probably do a better job of it in a number of places), so by using functions from there rather than rolling your own, the problem is reduced, but any time that you're doing a lot of generic string processing, there's a decent chance that you're going to have to special case some stuff for arrays of char, wchar, and dchar in order to fully optimize it. And I don't think that there's really a way out of that beyond having a lot of functions already available (and already optimized) to do a lot of the string processing for you. There's a definite tension between genericity and effciency in the case of string processing - due primarily to variable length encodings. - Jonathan M Davis
Re: Stack overflow / recursive expansion with alias this
On Tuesday, 24 April 2012 at 19:34:26 UTC, Timon Gehr wrote: On 04/24/2012 07:09 PM, Namespace wrote: ... And therefore i get the same error, as if i wrote "return NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the "_convert" method of NotNull. The Output is "Stack overflow". I think that comes from recursive calls which fills the stack? Is that a bug? Yes. I found nothing like that. Is the bug reported? I remember reporting a similar issue, but that one seems to have been fixed. Feel free to create a new ticket. That's what I do now. Thanks a lot for your help.
Re: Stack overflow / recursive expansion with alias this
On 04/24/2012 07:09 PM, Namespace wrote: ... And therefore i get the same error, as if i wrote "return NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the "_convert" method of NotNull. The Output is "Stack overflow". I think that comes from recursive calls which fills the stack? Is that a bug? Yes. I found nothing like that. Is the bug reported? I remember reporting a similar issue, but that one seems to have been fixed. Feel free to create a new ticket.
Re: Recommended way to access numeric_limits epsilon()
On Tuesday, 24 April 2012 at 18:48:15 UTC, H. S. Teoh wrote: On Tue, Apr 24, 2012 at 08:36:34PM +0200, digitalmars-d-learn-boun...@puremagic.com wrote: What is the recommended way to access the equivalent of numeric_limits epsilon() in D? I am searching especially for the double version. http://www.cplusplus.com/reference/std/limits/numeric_limits/ Check this page: http://dlang.org/property.html under "Properties for Floating Point Types". --T Thanks a lot.
Re: Object Serialization?
On 2012-04-24 18:42, dcoder wrote: Hello. I'm probably not looking hard enough, but Do we have any standard d-library for serializing an object/object tree into -for example- an xml file? thanks. You can have a look at Orange: https://github.com/jacob-carlborg/orange Tutorials: http://dsource.org/projects/orange/wiki/Tutorials API reference: http://dl.dropbox.com/u/18386187/orange_docs/orange.serialization.Serializer.html -- /Jacob Carlborg
Re: Recommended way to access numeric_limits epsilon()
On Tue, Apr 24, 2012 at 08:36:34PM +0200, digitalmars-d-learn-boun...@puremagic.com wrote: > What is the recommended way to access the equivalent of > numeric_limits epsilon() in D? I am searching especially for the > double version. > > http://www.cplusplus.com/reference/std/limits/numeric_limits/ Check this page: http://dlang.org/property.html under "Properties for Floating Point Types". --T
Recommended way to access numeric_limits epsilon()
What is the recommended way to access the equivalent of numeric_limits epsilon() in D? I am searching especially for the double version. http://www.cplusplus.com/reference/std/limits/numeric_limits/
Re: How to pass list of strings as compile-time parameters?
On Tue, Apr 24, 2012 at 08:03:07PM +0200, Timon Gehr wrote: > On 04/24/2012 07:37 PM, H. S. Teoh wrote: > >I'm trying to write a template function for doing member-wise > >comparisons between two objects, with an optional list of members to > >ignore. But I can't seem to figure out the syntax for passing a list of > >strings (or an AA of strings) to the function? > > > >I tried this: > > > > bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { > > foreach (name; __traits(getAllMembers, T)) { > > ... > > } > > } > > > >but the compiler complains: > > > > Error: arithmetic/string type expected for value-parameter, not string[] [...] > Try using an alias parameter (with an optional type constraint). imo > the template instantiation semantics needs a clean-up. Thanks, that did it! For posterity, here's the code (which I think is generally usable for many more things than I'm using it for in my code): bool membCmp(T)(T t1, T t2) { return membCmpIgnoring!(cast(string[])[])(t1, t2); } bool membCmpIgnoring(alias ignores, T)(T t1, T t2) if (is(typeof(ignores)==string[])) { nextMemb: foreach (name; __traits(allMembers, T)) { foreach (i; ignores) { if (name == i) continue nextMemb; } static if (__traits(compiles, &__traits(getMember, t1, name))) { alias typeof(__traits(getMember, t1, name)) type; static if (!is(type==function)) { auto val1 = __traits(getMember, t1, name); auto val2 = __traits(getMember, t2, name); if (val1 != val2) return false; } } } return true; } Given two structs or objects, X and Y, this lets you do an easy implementation of opEquals(): bool opEquals(Object obj) { auto o = cast(typeof(this))obj; return obj && membCmp(this, o); } If you wish to ignore some fields, say x and y, in the comparison, then just do this: bool opEquals(Object obj) { auto o = cast(typeof(this))obj; return obj && membCmpIgnoring!(["x", "y"])(this, o); } Question: is it possible to sugar up the syntax even more, by allowing an array of aliases? Or is that pushing the template syntax a bit too far? I.e., can we make it possible to write: membCmpIgnoring!(x,y)(this, o) without the string list syntax? T -- Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
Re: How to pass list of strings as compile-time parameters?
On 04/24/2012 07:37 PM, H. S. Teoh wrote: I'm trying to write a template function for doing member-wise comparisons between two objects, with an optional list of members to ignore. But I can't seem to figure out the syntax for passing a list of strings (or an AA of strings) to the function? I tried this: bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { foreach (name; __traits(getAllMembers, T)) { ... } } but the compiler complains: Error: arithmetic/string type expected for value-parameter, not string[] What gives? T Try using an alias parameter (with an optional type constraint). imo the template instantiation semantics needs a clean-up.
Re: How to pass list of strings as compile-time parameters?
On Tue, Apr 24, 2012 at 10:47:53AM -0700, H. S. Teoh wrote: > On Tue, Apr 24, 2012 at 07:39:42PM +0200, Trass3r wrote: > > > bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { > > > foreach (name; __traits(getAllMembers, T)) { > > > ... > > > } > > > > In this particular case you could try > > > > foo(T, U...)(T obj1, T obj2, U ignores) > > Sure, but U always string. Though I suppose I *could* use a signature > constraint to enforce that... [...] Well actually, U is a type tuple... but I want to constrain it to be always a tuple of strings. How would that work? T -- It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels.
Re: How to pass list of strings as compile-time parameters?
On Tue, Apr 24, 2012 at 07:39:42PM +0200, Trass3r wrote: > > bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { > > foreach (name; __traits(getAllMembers, T)) { > > ... > > } > > In this particular case you could try > > foo(T, U...)(T obj1, T obj2, U ignores) Sure, but U always string. Though I suppose I *could* use a signature constraint to enforce that... T -- Guns don't kill people. Bullets do.
Re: How to pass list of strings as compile-time parameters?
bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { foreach (name; __traits(getAllMembers, T)) { ... } In this particular case you could try foo(T, U...)(T obj1, T obj2, U ignores)
How to pass list of strings as compile-time parameters?
I'm trying to write a template function for doing member-wise comparisons between two objects, with an optional list of members to ignore. But I can't seem to figure out the syntax for passing a list of strings (or an AA of strings) to the function? I tried this: bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { foreach (name; __traits(getAllMembers, T)) { ... } } but the compiler complains: Error: arithmetic/string type expected for value-parameter, not string[] What gives? T -- Recently, our IT department hired a bug-fix engineer. He used to work for Volkswagen.
Re: Stack overflow / recursive expansion with alias this
... And therefore i get the same error, as if i wrote "return NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the "_convert" method of NotNull. The Output is "Stack overflow". I think that comes from recursive calls which fills the stack? Is that a bug? Yes. I found nothing like that. Is the bug reported?
Re: Why has base class protection been deprecated?
On Tuesday, 24 April 2012 at 12:22:14 UTC, David Bryant wrote: This bothers me for two reasons: firstly it's not a base class, and secondly, it's a standard OO pattern of mine. What's up with this? Generally (and slightly inaccurately) speaking, D follows the Java model for inheritance rather than the C++ one, where base class protection attributes simply do not exist. Besides that, I'm not quite sure what privately inheriting an interface would buy you – there would be no implementation to inherit anyway (except for final interface methods, but I doubt a valid use case for this would be easy to find)? David
Re: Object Serialization?
On Tuesday, 24 April 2012 at 16:42:19 UTC, dcoder wrote: I'm probably not looking hard enough, but Do we have any standard d-library for serializing an object/object tree into -for example- an xml file? There is no standard library support yet, but you might want to look at Orange (full fledged D serialization library) or the msgpack/Thrift D implementations (fast, lightweight, written with primarily RPC in mind). David
Object Serialization?
Hello. I'm probably not looking hard enough, but Do we have any standard d-library for serializing an object/object tree into -for example- an xml file? thanks.
Re: Keyword to avoid not null references
After i'm sure, that this is a bug: Great work again. If this bug will be fixed soon or someone can help me to find a workaround, then NotNull would be exactly what I always wanted.
Re: Nested RegEx
== Auszug aus Dmitry Olshansky (dmitry.o...@gmail.com)'s Artikel > On 21.04.2012 22:46, H. S. Teoh wrote: > > On Sat, Apr 21, 2012 at 09:41:18PM +0400, Dmitry Olshansky wrote: > >> On 21.04.2012 21:24, nrgyzer wrote: > >>> Hi guys, > >>> > >>> I'm trying to use std.regex to parse a string like the following: > >>> > >>> string myString = "preOuter {if condition1} content1 {if condition2} content2 > >>> {elseif condition3} content3 {else}any other content{/if}{/if} postOuter"; > >>> > >> > >> Simply put pure regex is incapable of arbitrary-nested if-else > >> statements. In a sense if... /if is a case of balanced parens > >> problem and it's widely know to form non-regular language. > > > > This is of theoretical interest to me. Very often I find myself wanting > > a concise way to express patterns with nested matching delimiters, but > > regexes can't do it. But to jump to a full-blown stack-based language > > seems like an overkill to me: stack languages can express *much* more > > than just nested delimiters, most of which is difficult to encapsulate > > in a nice, concise syntax like regexes. All I want is a simple way to > > express the kind of simple nesting that matching delimiters give. > > > Recursive descent is not particularly bad unless minimal "grammar > descent depth" is high. Example: > a+b-c > uses a quite a lot of recursive calls for grammar with e.g. 10+ operator > precedence levels. > I'm thinking of merging operator precedence parser with regex might be a > happy marriage you know. > Back to OP topic something along the lines of this will do it (beware of > stack overflow): > void parseIf(){ > static int ifNest; > if(input.startWith("{if")){ > ifNest++; > scope(exit) ifNest--; > enforce(ifNest < 1, "conservative stack overflow"); > parseCond(input[2..$-1]);//regex that does condition > enforce(input[$-1] == '}', "close that if"); > parseIf();//parse body or another nested if > //parseElse();//goes here, as does elif > } > else > parseBody();// the regex you used before > } > > > > [...] > >> One day I may add push-pop stack extensions (that allow this kind of > >> thing) into regex but I'd have to think hard to make it efficient. > > [...] > > > > Plus, have a nice concise syntax for it (otherwise I might as well just > > write a recursive descent parser for it in the first place). > > > Concise syntax & lots of power is a priority actually, because I can > detect if push-pop stuff is used or not and pick the right engine for > the job. So different big-oh complexity is not important. Thanks guys... I just solved the problem by using indexOf() from std.string for parsing my if-statements. So... in principle, I can have unlimited nested if- statements, but I think it's much more difficult (and slower) than using any regex-expression.
Re: Forcing static foreach
Am 24.04.2012 16:34, schrieb Robert Clipsham: enum foo = TT!("a", "b", "c"); alias TT!("a", "b", "c") foo; btw. there is std.typecons : TypeTuple with helpers (like staticMap)
Re: avoid toLower in std.algorithm.sort compare alias
On Tuesday, 24 April 2012 at 14:54:48 UTC, Steven Schveighoffer wrote: On Tuesday, 24 April 2012 at 11:24:44 UTC, Regan Heath wrote: After watching Andrei's talk on generic and generative programming I have to ask, which routines are you avoiding .. it seems we need to make them as good as the hand coded code you've written... from memory (don't have the code in front of me right now), it was std.uni.decode, and using foreach(dchar d; str) (which cannot be inlined currently). IIRC, std.uni.decode was not being inlined. So I tried hand-inlining it (I also discovered some optimizations it was not using), and it made a huge difference. BTW, you can check out my github branch of phobos named new-io2, look at the textstream struct to see what I've inlined. -Steve
Re: avoid toLower in std.algorithm.sort compare alias
On Tuesday, 24 April 2012 at 11:24:44 UTC, Regan Heath wrote: On Mon, 23 Apr 2012 16:43:20 +0100, Steven Schveighoffer wrote: While dealing with unicode in my std.stream rewrite, I've found that hand-decoding dchars is way faster than using library calls. After watching Andrei's talk on generic and generative programming I have to ask, which routines are you avoiding .. it seems we need to make them as good as the hand coded code you've written... from memory (don't have the code in front of me right now), it was std.uni.decode, and using foreach(dchar d; str) (which cannot be inlined currently). IIRC, std.uni.decode was not being inlined. So I tried hand-inlining it (I also discovered some optimizations it was not using), and it made a huge difference. In regards to this discussion, I think icmp can also be improved when run on a char array, by doing a byte comparison (no dchar decoding) until it finds a difference. That might be a huge speedup. Right now, all dchars are being decoded, and translated to the toLower counterpart. It may have an opposite effect, however, if there are a lot of strings that are equivalent when ignoring case, but not exactly the same. -Steve
Forcing static foreach
Is there anyway to force a static foreach to occur? template TT(T...) { alias T TT; } void main() { // This works foreach(s; TT!("a", "b", "c")) { mixin(`int ` ~ s ~ `;`); } enum foo = TT!("a", "b", "c"); // This fails foreach(s; foo) { mixin(`int ` ~ s ~ `;`); } } Thanks, -- Robert http://octarineparrot.com/
Re: Why has base class protection been deprecated?
On 04/24/2012 11:47 PM, David Bryant wrote: On 04/24/2012 11:07 PM, Don Clugston wrote: On 24/04/12 15:29, David Bryant wrote: Because it doesn't make sense. All classes are derived from Object. That _has_ to be public, otherwise things like == wouldn't work. Does the same apply for interfaces? I'm specifically implementing an interface with non-public visibility. This shouldn't affect the visibility of the implicit Object base-class. Right. Only classes are affected. Ok...so I still don't understand why the original example shouldn't compile. I'm not trying to change the visibility of the base class but rather the visibility of the interface. To be clear: my subject line is misleading. I used that text because it's what came out of the compiler's mouth. I do understand your reasoning why you can't change the visibility of a base class, just not for an interface.
Re: Why has base class protection been deprecated?
On 04/24/2012 11:07 PM, Don Clugston wrote: On 24/04/12 15:29, David Bryant wrote: Because it doesn't make sense. All classes are derived from Object. That _has_ to be public, otherwise things like == wouldn't work. Does the same apply for interfaces? I'm specifically implementing an interface with non-public visibility. This shouldn't affect the visibility of the implicit Object base-class. Right. Only classes are affected. Ok...so I still don't understand why the original example shouldn't compile. I'm not trying to change the visibility of the base class but rather the visibility of the interface.
Re: D 50% slower than C++. What I'm doing wrong?
Am Sat, 14 Apr 2012 21:05:36 +0200 schrieb "ReneSac" : > I have this simple binary arithmetic coder in C++ by Mahoney and > translated to D by Maffi. I added "notrow", "final" and "pure" > and "GC.disable" where it was possible, but that didn't made much > difference. Adding "const" to the Predictor.p() (as in the C++ > version) gave 3% higher performance. Here the two versions: > > http://mattmahoney.net/dc/ <-- original zip > > http://pastebin.com/55x9dT9C <-- Original C++ version. > http://pastebin.com/TYT7XdwX <-- Modified D translation. > > The problem is that the D version is 50% slower: > > test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes) > > Lang| Comp | Binary size | Time (lower is better) > C++ (g++) - 13kb - 2.42s (100%) -O3 -s > D(DMD) - 230kb - 4.46s (184%) -O -release -inline > D(GDC) -1322kb - 3.69s (152%) -O3 -frelease -s > > > The only diference I could see between the C++ and D versions is > that C++ has hints to the compiler about which functions to > inline, and I could't find anything similar in D. So I manually > inlined the encode and decode functions: > > http://pastebin.com/N4nuyVMh - Manual inline > > D(DMD) - 228kb - 3.70s (153%) -O -release -inline > D(GDC) -1318kb - 3.50s (144%) -O3 -frelease -s > > Still, the D version is slower. What makes this speed diference? > Is there any way to side-step this? > > Note that this simple C++ version can be made more than 2 times > faster with algoritimical and io optimizations, (ab)using > templates, etc. So I'm not asking for generic speed > optimizations, but only things that may make the D code "more > equal" to the C++ code. I noticed the thread just now. I ported fast paq8 (fp8) to D, and with some careful D-ification and optimization it runs a bit faster than the original C program when compiled with the GCC on Linux x86_64, Core 2 Duo. As others said the files are cached in RAM anyway if there is enough available, so you should not be bound by your hard drive speed anyway. I don't know about this version of paq you ported the coder from, but I try to give you some hints on what I did to optimize the code. - time portions of your main() is the time actually spent at start up or in the compression? - use structs, where you don't classes don't make your code cleaner - where ever you have large arrays that you don't need initialized to .init, write: int[] arr = void; double[] arr = void; This disables default initialization, which may help you in inner loops. Remember that C++ doesn't default initialize at all, so this is an obvious way to lose performance against that language. Also keep in mind that the .init for floating point types is NaN: struct Foo { double[99] bar; } Is not a block of binary zeroes and hence cannot be stored in a .bss section in the executable, where it would not take any space at all. struct Foo { double[99] bar = void; } On the contrary will not bloat your executable by 7,6 MB! Be cautious with: class Foo { double[99] bar = void; } Classes' .init don't go into .bss either way. Another reason to use a struct where appropriate. (WARNING: Usage of .bss on Linux/MacOS is currently broken in the compiler front-end. You'll only see the effect on Windows) - Mahoney used an Array class in my version of paq, which allocates via calloc. Do this as well. You can't win otherwise. Read up a bit on calloc if you want. It generally 'allocates' a special zeroed out memory page multiple times. No matter how much memory you ask for, it wont really allocate anything until you *write* to it, at which point new memory is allocated for you and the zero-page is copied into it. The D GC on the other hand allocates that memory and writes zeroes to it immediately. The effect is two fold: First, the calloc version will use much less RAM, if the 'allocated' buffers aren't fully used (e.g. you compressed a small file). Second, the D GC version is slowed down by writing zeroes to all that memory. At high compression levels, paq8 uses ~2 GB of memory that is calloc'ed. You should _not_ try to use GC memory for that. - If there are data structures that are designed to fit into a CPU cache-line (I had one of those in paq8), make sure it still has the correct size in your D version. "static assert(Foo.sizeof == 64);" helped me find a bug there that resulted from switching from C bitfields to the D version (which is a library solution in Phobos). I hope that gives you some ideas what to look for. Good luck! -- Marco
Re: Range of random numbers
trav...@phare.normalesup.org: That looks like a workarround, not meaningful code. It wasn't terrible code :-) How about return repeat(_ =>uniform(lower, upper)).map!(x => x())(); ? Why don't you write a little benchmark to compare the performance of the two versions? Using uniform(lower, upper, gen) with auto gen = Xorshift(1); to reduce influence from the random generator. Bye, bearophile
Re: Why has base class protection been deprecated?
On 24/04/12 15:29, David Bryant wrote: Because it doesn't make sense. All classes are derived from Object. That _has_ to be public, otherwise things like == wouldn't work. Does the same apply for interfaces? I'm specifically implementing an interface with non-public visibility. This shouldn't affect the visibility of the implicit Object base-class. Right. Only classes are affected.
Re: Stack overflow / recursive expansion with alias this
You missed the 'immutable' and 'inout cases. Just use inout(T) _get() inout { return _value; } instead of the two declarations you have. Oh, thanks a lot, i'm forgetting this often. ... And therefore i get the same error, as if i wrote "return NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the "_convert" method of NotNull. The Output is "Stack overflow". I think that comes from recursive calls which fills the stack? Is that a bug? Yes. Some ideas how i can implement this otherwise? And would the bug fix come with 2.060? With this functionality, the NotNull struct would be perfect.
Re: Why has base class protection been deprecated?
Because it doesn't make sense. All classes are derived from Object. That _has_ to be public, otherwise things like == wouldn't work. Does the same apply for interfaces? I'm specifically implementing an interface with non-public visibility. This shouldn't affect the visibility of the implicit Object base-class.
Re: D 50% slower than C++. What I'm doing wrong?
Am Sat, 14 Apr 2012 19:31:40 -0700 schrieb Jonathan M Davis : > On Sunday, April 15, 2012 04:21:09 Joseph Rushton Wakeling wrote: > > On 14/04/12 23:03, q66 wrote: > > > He also uses a class. And -noboundscheck should be automatically induced > > > by > > > -release. > > > > ... but the methods are marked as final -- shouldn't that substantially > > reduce any speed hit from using class instead of struct? > > In theory. If they don't override anything, then that signals to the compiler > that they don't need to be virtual, in which case, they _shouldn't_ be > virtual, but that's up to the compiler to optimize, and I don't know how good > it is about that right now. May I point to this: http://d.puremagic.com/issues/show_bug.cgi?id=7865 -- Marco
Re: Why has base class protection been deprecated?
On 24/04/12 14:22, David Bryant wrote: With the dmd 2.059 I have started getting the error 'use of base class protection is deprecated' when I try to implement an interface with private visibility, ie: interface Interface { } class Class : private Interface { } $ dmd test.d test.d(4): use of base class protection is deprecated This bothers me for two reasons: firstly it's not a base class, and secondly, it's a standard OO pattern of mine. What's up with this? Thanks, Dave Because it doesn't make sense. All classes are derived from Object. That _has_ to be public, otherwise things like == wouldn't work. Previously, the compiler used to allow base class protection, but it ignored it.
Why has base class protection been deprecated?
With the dmd 2.059 I have started getting the error 'use of base class protection is deprecated' when I try to implement an interface with private visibility, ie: interface Interface { } class Class : private Interface { } $ dmd test.d test.d(4): use of base class protection is deprecated This bothers me for two reasons: firstly it's not a base class, and secondly, it's a standard OO pattern of mine. What's up with this? Thanks, Dave
Re: Range of random numbers
"bearophile" , dans le message (digitalmars.D.learn:35108), a écrit : > What about (untested): > > auto uniformRange(T1 lower, T2 upper) { > return count().map!(_ => uniform(lower, upper))(); > } That looks like a workarround, not meaningful code. How about return repeat(_ =>uniform(lower, upper)).map!(x => x())(); ? We could also use a template to make a range out of a delegate and avoid this workarround... struct RepeatDg(T) { T delegate() dg; this(T delegate() dg_) { dg = dg_; } @property enum bool empty = false; @property T front() { return dg(); } @property void popFront() {} }
Re: avoid toLower in std.algorithm.sort compare alias
On Mon, 23 Apr 2012 16:43:20 +0100, Steven Schveighoffer wrote: While dealing with unicode in my std.stream rewrite, I've found that hand-decoding dchars is way faster than using library calls. After watching Andrei's talk on generic and generative programming I have to ask, which routines are you avoiding .. it seems we need to make them as good as the hand coded code you've written... R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Stack overflow / recursive expansion with alias this
On 04/23/2012 11:29 PM, Namespace wrote: I have this code: ... T _get() { return this._value; } const(T) _get() const { return this._value; } You missed the 'immutable' and 'inout cases. Just use inout(T) _get() inout { return _value; } instead of the two declarations you have. ... And therefore i get the same error, as if i wrote "return NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the "_convert" method of NotNull. The Output is "Stack overflow". I think that comes from recursive calls which fills the stack? Is that a bug? Yes.
Re: Stack overflow / recursive expansion with alias this
Hm, doesn't anybody know anything about it?
Re: Derelict2 openGL3 issues
One day I'll finish my OpenGL wrapper for D. It will give you better abilities in creating OpenGL 3 contexts than most C++ frameworks (SDL, GLFW etc.) and, I hope, will get rid of passing pointers to functions. It will be done soon after I'll finish Scintilla wrapper for D. And it will be done soon after I'll conquer the world (or a bit earlier). Dreams, dreams... P.S. OpenGL context creating has been done a long time ago but then I decided to create full wrapper to supersede Derelict's one and it still not finished because that I decided to create general wrapping back-end. And I've done it (CWrap), but than I decided to create Scintilla wrapper... P.P.S. Sorry for the flood... -- Денис В. Шеломовский Denis V. Shelomovskij
Re: Pacikage level access broken?
On 04/23/2012 07:43 PM, Jonathan M Davis wrote: On Monday, April 23, 2012 13:42:36 Jacob Carlborg wrote: On 2012-04-23 10:26, Era Scarecrow wrote: On Monday, 23 April 2012 at 06:19:12 UTC, Jacob Carlborg wrote: "public" is the default access level. So it is... That explains why the tests came out backwards on the results Wasn't it private by default in C++? I honestly don't know sometimes. I think so. If you use "class" it's private by default. If use "struct" it's public by default. That's basically the only difference between "class" and "struct" in C++, if I recall correctly. That's correct. In C++, struct and class are identical except that a class' members are private by default and a struct's members are public by default. - Jonathan M Davis The same holds for the default base class access.