file i/o in a variety of languages
bearophile
bearophileHUGS at lycos.com
Fri Aug 27 17:03:41 PDT 2010
Andrei:
> The open() method saves on reallocating the refcounted
> structured stored inside the File.
Thank you for your answer.
So the API is designed a bit larger than necessary for performance reasons.
This the reformatted first part of the interesting implementation of File:
struct File {
private struct Impl {
FILE* handle = null;
uint refs = uint.max / 2;
string name = null;
this(FILE* h, uint r, string n) {
handle = h;
refs = r;
name = n;
}
}
private Impl* p;
this(string name, in char[] stdioOpenmode="rb") {
p = new Impl(errnoEnforce(.fopen(name, stdioOpenmode),
text("Cannot open file `", name, "' in mode `", stdioOpenmode, "'")),
1,
name);
}
~this() {
if (!p)
return;
if (p.refs == 1)
close;
else
--p.refs;
}
this(this) {
if (!p)
return;
assert(p.refs);
++p.refs;
}
void opAssign(File rhs) {
swap(p, rhs.p);
}
void open(string name, in char[] stdioOpenmode="rb") {
detach;
auto another = File(name, stdioOpenmode);
swap(this, another);
}
Few comments:
I am slowly starting to understand the purpose of that Impl :-) It allows to use File as as a class instance, as it is by reference.
According to D specs on the site, inner structs contain an extra scope pointer, so this may be better:
private static struct Impl {
I have seen the same problem in other parts of Phobos (see bug http://d.puremagic.com/issues/show_bug.cgi?id=4087 ).
open() contains:
auto another = File(name, stdioOpenmode);
That calls File.this(), so isn't it creating a new Impl anyway? I don't understand the performance gain still.
Given the presence of opAssign, I presume this code:
auto another = File(name, stdioOpenmode);
swap(this, another);
May be written just as:
this = File(name, stdioOpenmode);
Bye and thank you,
bearophile
More information about the Digitalmars-d
mailing list