Re: discrimination of constructors with same number of parameters
On 12/30/2010 08:46 AM, Lutger Blijdestijn wrote: sybrandy wrote: Why not have something like this: this (int[] data, string text, bool isMessage = false) {...} Then, if you just pass in two parameters you treat it as a filename and if you pass in a "true" for the third parameter, it's a message. It's not quite what you're looking for, but it's simple and pretty clean. Casey If you opt for this solution, an enum is slightly more verbose but much clearer: enum IsMessage { Yes, No } this (int[] data, string text, IsMessage isMessage = IsMessage.No) {...} auto s = new S(data, text, IsMessage.Yes); vs auto s = new S(data, text, true); I will agree that is clearer. I just had to do stuff like this for different reasons and it worked very nicely. I would still prefer a factory method or a struct wrapper though. True, I just don't know how without it being complex. I think this may be the case where improvements to the type system would be useful. For me, this situation doesn't come up very often, so I'm not all that concerned, but I do see where this can be useful. I'm just not a fan of having to write a lot of code to do something that the language can turn into something simple. However, another possible solution that just occurred to me is something like this (please forgive any typos, I haven't done inheritance in D yet): enum TextType { Filename, Message } class Text { string text; TextType type; bool isMessage() { return TextType.Message == this.type; } } class Filename : Text { this(int[] data, string txt) { this.type = TextType.Filename; this.text = txt; // Do something with data... } } class Message : Text { this(int[] data, string txt) { this.type = TextType.Message; this.text = txt; // Do something with data... } } Then, you can do something like this: Text foo = new Filename(data, filename); Text bar = new Message(data, message); Not sure if it's any better than using an enum, but it still has the clarity that you're looking for. Casey
Re: discrimination of constructors with same number of parameters
Why not have something like this: this (int[] data, string text, bool isMessage = false) {...} Then, if you just pass in two parameters you treat it as a filename and if you pass in a "true" for the third parameter, it's a message. It's not quite what you're looking for, but it's simple and pretty clean. Casey
Re: Creating an array of unique elements
I've done something like this before using associative arrays. I would rely on the fact that the keys have to be unique to produce my unique array. So, in this case, any value you want to store you would save like this: array[value] = 1; Regardless of whether or not the value already exists, this will work and ensure uniqueness of the keys. To determine if a value is already part of the array, you can check for the key like this: if (value in array) You can later get the values like this: values = array.keys; Not sure if this will do everything you want, but it seems to be cleaner than having to ensure an array is unique after every insertion. Casey
Re: Memory allocation faile on string concat
On 11/10/2010 11:33 AM, Xie wrote: Can't run a simple program. What's wrong, GC? import std.stdio; import std.date; void f0() { wstring a[]; foreach(i; 0 .. 100_000_000) { a ~= " "w; } } void main() { auto r = benchmark!(f0)(1); writeln(r, "ms"); } DMD 2.047 In addition to what everybody else is suggesting you look at, you may want to look into using an appender (defined in std.array). Not sure if it will help with the memory usage, but it's supposed to be faster for appending data to an array. Casey
Exception with MmFile
Hello, I'm currently getting a message stating that an exception has been thrown when finalizing an instance of std.mmfile.MmFile. What would cause this? I've used MmFile in other cases without any problems. However, in this case I'm using it as a member within a class. I see nothing in the std.mmfile documentation that suggests that I need to do anything special. Any thoughts? Casey
RosettaCode: Echo Server
Hello, I decided to exercise my skills in D a bit and wrote an implementation for an echo server using D. I figure before I post it to the site, I'd post it here for comments as I'd like to get the best possible version on the site vs. something that's half-assed. Considering I'm very new to socket programming, I'm guessing this may not be the best possible version. Attached are two files: a client and a server. Let me know what you think. Casey import std.socket; import std.stdio; import std.string; void main() { Socket sock = new TcpSocket(new InternetAddress("localhost", 12321)); string[4] messages = ["Hello world.", "Hello\nworld.", "\tHello world.", "Goodby cruel world..."]; ubyte buff[1]; int bytesRead; foreach (msg; messages) { sock.send(msg); for (int i = 0; i < msg.length; i++) { bytesRead = sock.receive(buff); write(cast(char)buff[0]); } /* string temp = cast(string)buff; writeln(temp, "\n"); */ write("\n"); } sock.close(); } import std.socket; import std.array; void main() { Socket listener = new TcpSocket; assert(listener.isAlive); listener.bind(new InternetAddress(12321)); listener.listen(10); Socket currSock; uint bytesRead; ubyte buff[1]; while(1) { currSock = listener.accept(); while ((bytesRead = currSock.receive(buff)) > 0) { currSock.send(buff); } currSock.close(); buff.clear(); } }
Re: typedef alternative
I can't recall if you can do this with structs, but if you use classes, you should be able to define a "Date Part" class that has all of the methods and data you want. Then, you just derive three sub-classes. For example (and I hope the syntax is right): class DatePart { this(int f) { _foo = f; } int asNumber() { return _foo; } immutable int _foo; } class Year: DatePart {} class Month: DatePart {} class Day: DatePart {} Casey On 08/14/2010 08:47 PM, Yao G. wrote: Hello. Is there an alternative to typedef? I need to define three structs that have exactly the same methods and properties, yet represent different stuff. Example: --- struct Foo { this( int f ) { _foo = f; } int asNumber() { return _foo; } private immutable int _foo; } // This should be typedef, but as it's going to be deprecated... alias Foo Year; alias Foo Month; alias Foo Day; void bar( Year y, Month m, Day d ) { // ... } // This should compile, obviously. bar( Year(2010), Month(8), Day(14) ); // But this shouldn't bar( Day(1), Year(1), Month(1) ); --- So, what options do I have? I know that typedef is scheduled to deprecation, so I would like to know if there's something else.
Re: Grokking concurrency, message passing and Co
I'd expect databases to have quite odd performance characteristics compared to a more normal application though; You'd expect them to be IO bound most of the time, so having more threads than cores sounds like a reasonable thing to do. If you aren't waiting on the disc, then more threads aren't going to help, they'll just be contending for cpu time as BCS said. Still that's one of the drawbacks with multi threading, there's really not many absolute statements you can make or things you can assume. You'll have to profile you application and fiddle with it to find out how to get the best performance out of it. Yeah, that was my assumption. It just sounded like there was more to it. Thanks. Casey
Re: Grokking concurrency, message passing and Co
The rule of thumb is don't bother spawning more threads than you have cpus. You're just wasting resources mostly. You REALLY don't want more threads trying to run than you have cores. Threads in a wait state, are less of an issue, but they still use up resources. Personally I'd never use more threads than cores as a program design, but I'm a performance whore. ;) Could you explain why you believe this a bit more? I'm curious because I've worked with databases and the rule of thumb there was you should configure them to use twice as many threads as number of cores/CPUs. The reasoning, I believe, is that if one thread on the CPU is stalled, another thread can execute in it's place. And yes, I believe this was before hyperthreading. Though I wasn't informed of the specifics as to why, I'm guessing it's mainly because with a database, there's a good chance you have to perform some sort of disk I/O. Therefore instead of having the CPU wait while the I/O is occurring, another thread can start executing while the original is waiting. Casey
Re: Issue with Curry
On 06/24/2010 06:54 PM, sybrandy wrote: Hello, I tried using the curry function last night and I ran into a compilation issue. Here's a simple example that demonstrates the issue: import std.functional; import std.stdio; void strwrite(string input) { writeln(input); } alias curry!(strwrite, "foo") writefoo; void main() { writefoo(); } And the error message: /apps/dmd2/linux/bin/../../src/phobos/std/functional.d(303): Error: tuple index 1 exceeds 1 /apps/dmd2/linux/bin/../../src/phobos/std/functional.d(9): Error: template instance std.functional.curry!(strwrite,"foo") error instantiating The examples I found in the documentation used ints, IIRC, however I don't recall seeing anything that would prevent me from using a string in this case. Am I doing something wrong or did I find an issue? Casey Forgot to mention: this is occurring with the newest version of D2. (2.0.47)
Issue with Curry
Hello, I tried using the curry function last night and I ran into a compilation issue. Here's a simple example that demonstrates the issue: import std.functional; import std.stdio; void strwrite(string input) { writeln(input); } alias curry!(strwrite, "foo") writefoo; void main() { writefoo(); } And the error message: /apps/dmd2/linux/bin/../../src/phobos/std/functional.d(303): Error: tuple index 1 exceeds 1 /apps/dmd2/linux/bin/../../src/phobos/std/functional.d(9): Error: template instance std.functional.curry!(strwrite,"foo") error instantiating The examples I found in the documentation used ints, IIRC, however I don't recall seeing anything that would prevent me from using a string in this case. Am I doing something wrong or did I find an issue? Casey
Appending to Shared Arrays
Hello, I have a shared array that I'm trying to append data to, but the compiler keeps telling me that I can't convert to a shared(Fiber) from a regular or const Fiber. What is the correct way to do this? Casey
Re: raii
I have two questions for you: 1) Are class destructors not good enough? If so, why? 2) Have you looked into static destructors? I created a logging library and that worked perfect for me to ensure that if I killed the program via Ctrl-C, it would flush the output buffer and close the file handle. Personally, I really like the use of "scope" vs. RAII. Keeping the code to clean up a file handle or the like right by where it's declared seems very sensible to me. Casey
Re: Simple Socket Server Code
On 02/24/2010 09:00 AM, daoryn wrote: Check the "samples" dir inside the dmd instalation folder. Theres a sample there named "listener.d" that shows how to use D sockets. If you're using DMD2, the listener.d file is broken. You'll have to convert it into D2 yourself. I actually did look at that and it is more than I was looking for. I just wanted something akin to "Listen -> Accept -> Process -> Respond -> Repeat." Regardless, it turns out that my understanding was better than I thought. I just had a stupid little bug that I didn't notice was an actual compilation error at first. Guess that's what I get when I try to write code when tired... Anyway, thanks!
Simple Socket Server Code
All, Does anyone know where I can get a simple example of writing a server in D? Just a stupid little echo server would be fine. I'm trying to write one myself, but for some reason it doesn't seem to be accepting any connections. I figure it's something stupidly simple, but I'm just not seeing it. Perhaps a related question is: is there anything weird about creating a server on windows? I'm currently using D on a windows laptop, so perhaps this is a platform issue? I find it unlikely, but you never know. Thanks. Casey
Re: Creating a logging library and have questions
I second Rainer. A logging system should commit (at least) error messages immediately, particularly if the application has multiple threads. Otherwise it is going to make debugging a crashing system a nightmare. When I do it I just stick 'synchronized' in front of the statement that does the write. Yes, I fully understand that and in the current single-threaded version I have, that's exactly what happens: all error and fatal messages cause the buffer to flush. What I'm looking for is the best way to handle having a daemon writer. My biggest concern here is multi-threaded applications. Granted, it would be nice to not have the writing in the same thread as the rest of the code to try to keep file I/O from affecting performance, but that's secondary. Here's what I know: a variable of type OutputStream cannot be shared. I did not try using __gshared, but regardless while this would work and I could easily synchronize the writes, I can see a lot of contention if multiple threads trying to write a lot of data to a log file. (E.g. trace statements that capture variable states to enhance debugging) Granted, this shouldn't be the case in production code, but if I can find a better way to do this, I'd love to. This is why I thought that the new threading model with message passing would be good, but I again have concerns if there are a lot of messages trying to be written. I know in Erlang you can fill up the message buffer if you're not careful. Casey
Re: Creating a logging library and have questions
On 02/03/2010 12:03 AM, Rainer Deyke wrote: sybrandy wrote: 1) I use the current core.thread library and put all my messages in a buffer that the thread checks periodically, pulls off a new message, and then writes it to a file. There will be some work to make sure nothing collides with each other, but I think I can manage it. Wouldn't this allow logging messages to be lost before a hard crash? To me, that would greatly reduce the utility of the logging system. If done improperly, yes, it would. My hope is that if I did go with this method, I would try to find a way to ensure no data was lost. Oddly enough, I'm currently having that problem with the single-threaded version for some reason. The test program will stop and some of the logging statements never make it to the file. 3) Something else. I really don't have much experience with threading, so I'm being very careful and really want to understand it. This library looks to be a good way to learn, however if it's not the best way to do things, then what would be? Global mutex associated with the logging system. Lock, output, unlock. There are scalability issues with that approach, but I don't see why it wouldn't work in this situation. (Plus, if you have a message queue, you probably need to protect that queue with a mutex anyway.) Understood. My goal is that if I do put the writing in another thread, I do my best to ensure it will scale. I have a tendency to put a lot of logging statements in code when I'm trying to debug something, so I don't want to slow things down too much nor do I want to lose anything. In short: I want the log writing to be as out of the way as possible. Casey
Creating a logging library and have questions
Hello, Since I'm continuing to write software in D (no, nothing special...just pet projects) I felt that I needed to create a library to handle logging to a file. I have a good start and it seems to work pretty well. I even have a couple ideas left to implement to make it better, however I'm having trouble with one. One thing that I did implement, which I think is pretty cool, is a set up the class to start a thread as a daemon to run in the background and check for updates to the config file, much like log4j. This way the user can change the log level at runtime. One thing I'm thinking that I want to do is have the writing to the logfile handled by a separate class. This way I'm hoping to ensure that there's not a lot of unnecessary synchronizing going on and the amount of work writing to the logfile won't slow down the rest of the program. My question is, what is the best approach? 1) I use the current core.thread library and put all my messages in a buffer that the thread checks periodically, pulls off a new message, and then writes it to a file. There will be some work to make sure nothing collides with each other, but I think I can manage it. 2) I wait for the new threading library with message passing to come out and just rely on the message passing to handle everything. It's a much cleaner approach based on my experience with Erlang, but there are two issues and the major one is I have no idea when it'll be ready. Granted, I don't need this capability now, but I'm interested in getting it to work. 3) Something else. I really don't have much experience with threading, so I'm being very careful and really want to understand it. This library looks to be a good way to learn, however if it's not the best way to do things, then what would be? Thanks in advance for any input. Casey
Re: D memory consumption/runtime speed problem
Using a small buffer as suggested by Daniel Keep and Steven Schveighoffer significantly improved performance. Now down to about 5 seconds. I ended up using the static array buffer since the encodeNumber function will be in its own file in my resulting program, so I can keep it private. Doing something similar to the output buffer had a similar effect and it's now processing everything in less than 2 seconds! I didn't realize that all those little arrays were created. Perhaps this is something that should be detailed in the arrays documentation or, perhaps even better, an optimization guide? I honestly thought the GC would help keep memory in check as I didn't want to assume a worst-case scenario, which with my RLE implementation is 2 * input buffer size, but I guess I have to. Well, perhaps my original code will be of use if Walter and the gang decide to try to revamp the GC and want some "bad" code to test it with. Thanks all! Btw: below is the updated code import std.conv; import std.stdio; import std.stream; import std.date; import std.mmfile; import std.array; string filename = "enwik8_small"; private immutable uint ONE_BYTE_VAL = (1 << 6) - 1; private immutable uint TWO_BYTE_VAL = (1 << 14) - 1; private immutable uint THREE_BYTE_VAL = (1 << 22) - 1; private immutable uint FOUR_BYTE_VAL = (1 << 30) - 1; private immutable uint ONE_BYTE_MASK = (0 << 6); private immutable uint TWO_BYTE_MASK = (1 << 6); private immutable uint THREE_BYTE_MASK = (2 << 6); private immutable uint FOUR_BYTE_MASK = (3 << 6); private static ubyte[4] encodeBuff; ubyte[] encodeNumber(in uint count) { if (count <= ONE_BYTE_VAL) { encodeBuff[0] = cast(ubyte)(ONE_BYTE_MASK | count); return encodeBuff[0..1]; } else if (count <= TWO_BYTE_VAL) { encodeBuff[0] = cast(ubyte)(TWO_BYTE_MASK | (count >>> 8)); encodeBuff[1] = cast(ubyte)(count & 0x00ff); return encodeBuff[0..2]; } else if (count <= THREE_BYTE_VAL) { encodeBuff[0] = cast(ubyte)(THREE_BYTE_MASK | (count >>> 16)); encodeBuff[1] = cast(ubyte)((count >>> 8) & 0x00ff); encodeBuff[2] = cast(ubyte)(count & 0x00ff); return encodeBuff[0..3]; } else if (count <= FOUR_BYTE_VAL) { encodeBuff[0] = cast(ubyte)(FOUR_BYTE_MASK | (count >>> 24)); encodeBuff[1] = cast(ubyte)((count >>> 16) & 0x00ff); encodeBuff[2] = cast(ubyte)((count >>> 8) & 0x00ff); encodeBuff[3] = cast(ubyte)(count & 0x00ff); return encodeBuff[0..4]; } else { throw new Exception("Invalid count provided!"); } } void encode(in ubyte[] buff, ref ubyte[] output) { ubyte currByte = buff[0]; uint count = 0; uint outIdx = 0; ubyte[] temp; foreach (byteVal; buff) { if (byteVal != currByte && count > 0) { temp = encodeNumber(count); foreach (t; temp) { output[outIdx++] = t; } output[outIdx++] = currByte; currByte = byteVal; count = 0; } count++; } temp = encodeNumber(count); foreach (t; temp) { output[outIdx++] = t; } output[outIdx++] = currByte; } void benchCode() { MmFile buff = new MmFile(filename); ubyte[] encodedBytes; encodedBytes.length = cast(size_t)buff.length * 2; encode(cast(ubyte[])buff[], encodedBytes); } void main(string[] args) { filename = args[1]; writeln("Benchmark time: ", benchmark!(benchCode)(to!(uint)(args[2]))); }
D memory consumption/runtime speed problem
Hello, I've been writing a bit of compression code and I noticed some strange behavior that's driving me a bit batty. I don't know if it's a bug with D or something I did. All I know is I can't figure it out. Below is the simplified version of the code as a single file. It takes two parameters. The first is a file to "compress" and the second is the number of times to run the benchmark. E.g. bugtest foo.txt 2 Now, if I set the second parameter to 1, it runs decently fast. 26 seconds on my work laptop for a half-sized enwiki8 from the Hutter challenge. If I set it to 2, then it takes about 142 seconds. In both cases a lot of memory is used and I'm not really sure why. Also, after it prints out the results, it takes several seconds for the program to exit. Am I doing something wrong? I've tried every trick that I could find by reading the documentation. Btw: The last time I tried this was with the latest version of D released at the beginning of the month. __CODE__ import std.conv; import std.stdio; import std.stream; import std.date; import std.mmfile; import std.array; string filename = "enwik8_small"; private immutable uint ONE_BYTE_VAL = (1 << 6) - 1; private immutable uint TWO_BYTE_VAL = (1 << 14) - 1; private immutable uint THREE_BYTE_VAL = (1 << 22) - 1; private immutable uint FOUR_BYTE_VAL = (1 << 30) - 1; private immutable uint ONE_BYTE_MASK = (0 << 6); private immutable uint TWO_BYTE_MASK = (1 << 6); private immutable uint THREE_BYTE_MASK = (2 << 6); private immutable uint FOUR_BYTE_MASK = (3 << 6); ubyte[] encodeNumber(in uint count) { if (count <= ONE_BYTE_VAL) { return [cast(ubyte)(ONE_BYTE_MASK | count)]; } else if (count <= TWO_BYTE_VAL) { return [cast(ubyte)(TWO_BYTE_MASK | (count >>> 8))] ~ [cast(ubyte)(count & 0x00ff)]; } else if (count <= THREE_BYTE_VAL) { return [cast(ubyte)(THREE_BYTE_MASK | (count >>> 16))] ~ [cast(ubyte)((count >>> 8) & 0x00ff)] ~ [cast(ubyte)(count & 0x00ff)]; } else if (count <= FOUR_BYTE_VAL) { return [cast(ubyte)(FOUR_BYTE_MASK | (count >>> 24))] ~ [cast(ubyte)((count >>> 16) & 0x00ff)] ~ [cast(ubyte)((count >>> 8) & 0x00ff)] ~ [cast(ubyte)(count & 0x00ff)]; } else { throw new Exception("Invalid count provided!"); } } void encode(in ubyte[] buff, out ubyte[] output) { ubyte currByte = buff[0]; uint count = 0; auto appOutput = appender(&output); foreach (byteVal; buff) { if (byteVal != currByte && count > 0) { appOutput.put(encodeNumber(count)); appOutput.put(currByte); currByte = byteVal; count = 0; } count++; } appOutput.put(encodeNumber(count)); appOutput.put(currByte); } void benchCode() { MmFile buff = new MmFile(filename); ubyte[] encodedBytes; encode(cast(ubyte[])buff[], encodedBytes); } void main(string[] args) { filename = args[1]; writeln("Benchmark time: ", benchmark!(benchCode)(to!(uint)(args[2]))); }
Re: D2 Singleton / Thread Local Storage issue
Thanks for the info. I was hoping that there would be a different solution, but I guess I should have expected that I may have to wait for the feature to stabilize. Casey
D2 Singleton / Thread Local Storage issue
Hello, I've been learning D for some time now and I recently was trying to do some work with threads, but I'm having a problem getting it to work. I'm trying to create a singleton that can be accessed between threads, however I get an access violation when I try to run the following code. If I make the variable "instance" shared, I get a compilation error. Is there something I'm missing? Thanks in advance. Casey import std.stdio; import core.thread; class Simple { string buff; public: static Simple instance; void setMsg(string msg) { buff ~= msg; } string getMsg() { string temp = buff.idup; buff.length = 0; return temp; } private: this() {} static this() { instance = new Simple; } } class ThrTest : Thread { this() { super(&run); } private: void run() { auto var = Simple.instance; var.setMsg("foo"); writeln("message: " ~ var.getMsg()); } } void main() { Thread t = new ThrTest(); t.start(); t.join(); writeln("Finished testing Simple.d"); }