Mark Dufour wrote:
>
> that's great, thanks! I was hoping someone would look into this,
> because my own strings methods were mostly made correctness, and I'm
> too busy with other parts of the compiler..
That's good, because C++ is my thing, not generating code... =)
> well, it is not very much complicated..? there is some GC stuff in
> builtin_.hpp, but mostly to add gc_allocators to the used STL types. I
> have actually used this GC so I wouldn't have any worries about it..
> but if 'smart pointers' can increase performance, I would gladly look
> into them.. I'll try to read about them tonight, but maybe you can
> explain what they are? :-)
Well they aren't terribly complex, but when I sat down to modify the
code, I had to scratch my head for a while to figure out what was going
on. For example, take this code snippet:
str *str::replace(str *a, str *b) {
__GC_STRING s = unit;
int i;
while( (i = s.find(a->unit)) != -1 )
s.replace(i, a->unit.size(), b->unit);
return new str(s.c_str());
}
At first I had a hard time understanding why there are both __GC_STRING
and str (I eventually figured it out), but what I am suggesting would
look something like this:
str str::replace(str a, str b) {
str toReturn(*this);
int i;
while( (i = toReturn->find(a)) != -1 )
s.replace(i, a->size(), b);
return toReturn;
}
Or very similar at least. A smart pointer does two things. First it
wraps a standard pointer with a reference counter in almost exactly the
same way CPython does it, only you do not have to ever call incref or
decref (it is done automatically). This means that you never have to
explicitly call new and delete on the object, you simply pass around
these shared pointer objects as if they are python objects and it will
take care of memory management when things go out of scope. The second
thing is a shared pointer acts like a regular pointer. As you see from
the code above, we have removed the pointer marker (str *) and replaced
it with just (str).
Don't get me wrong, this is not a panacea for all problems here.... It
is my belief that replacing the GC with smart pointers on classes will
most certainly increase the readability/maintainability of the code. It
should also increase the safety of the code, because we can add assert
statements every time a call is made to ensure the object is valid
(which are optimized away if you do not define _DEBUG on the command
line, incurring no performance penalty in the actual application).
Lastly, I *believe* that it will improve the performance of some areas
of the code (though not every area for sure).
With a garbage collector you are incurring penalty every time you
malloc, free, new, or delete anything. With shared pointers you incur a
lesser penalty for any new/delete operation, and do not have the
malloc/free penalty. With a GC, you incur a penalty when you copy STL
objects (basically anything that touches said allocator), and with smart
pointers you spend more time copying the actual pointer itself. Which
is actually faster really needs to be benchmarked/profiled to be sure,
which is why I propose making the changes and testing it to see.
Even if the smart pointers turn out to be slower (and it wouldn't be by
much if they did), you still gain having an explicitly stated cleanup
routine. For example, this code rather bothers me as a C++ programmer:
int __main() {
const_0 = new str("this is a test");
const_1 = new str("test");
s = const_0;
end = const_1;
i = 0;
while((i<100000000)) {
s->endswith(end);
i += 1;
}
}
Because when are const_0 and const_1 deleted? There are many places in
the code where we blindly return "new [object]()", but I've never seen
cleanup code. I am assuming that the GC magically cleans these up
somehow (maybe?), but this is throwing red warning lights off in my
head. Does the GC take care of this or are we just leaking massive
amounts of memory? Even if we are not leaking memory it makes more
sense to a C++ programmer new to the project that we are dealing with
smart pointers than to spend the time searching for memory leaks that
may or may not exist.
Anyway, that's basically the arguments for and against smart pointers in
a nutshell. I'll see what I can do getting an implementation together
to run tests on. Then you can make the final decision about it. (It
will be a few days, I have a busy two weeks.)
> you mean simply adding 'inline' to each math method? as you may have
> seen from the C++ code, I am not a C++ expert.. :-) (not even a Python
> one - I've used mostly C before).
Roughly yes, but also moving the definition to the .hpp file. This:
double ceil(double x);
double fabs(double x);
Would become:
inline double ceil(double x) {
return std::ceil(x);
}
inline double fabs(double x) {
return std::fabs(x);
}
And removing the math_.cpp file would enable inlining for all
compilers. Moving the function definition from the .cpp to the .hpp
file is required for older compilers which do not understand how to
search for the function body for an inlined function.
Clay
|