Quickie: Buffering techniques

| | Comments (10)

Have you ever needed a scratch buffer for doing graphics operations? Something that you can use for double buffering, for instance? Here's a handy tip to speed your applications up by reducing the number of times you need to make a new scratch buffer.
[rbcode]
Function Buffer( width as Integer, height as Integer ) as Picture
static temp as Picture

if temp = nil or temp.Width < width or temp.Height < height then
temp = new Picture( width, height, 32 )
end if

return temp
End Function[/rbcode]
The beauty of using code like this is that the buffer storage is only created if it currently can't meet your needs. So if you need a buffer that's 10x10, then this will make a 10x10 buffer for you. Then, if you need one that's 100x100, it'll make a 100x100. But if you need another 10x10, then it won't waste time making a new buffer for you -- it just hands you back what it has, since it'll meet your needs.

10 Comments

Allowing us to change the width and height of pictures would be a nice addition to the language and framework. This would have to be implemented in a very efficient manner behind the scenes to be useful.

Of course, the big gotcha here is a second call to get a temp buffer while the first user still has it. Not a problem if the new buffer request needs a new picture, but it will be bad if the existing buffer fulfills the request. Now, if we had access to the internal refcounts, you could make this routine safe by allocating a new buffer if the refcount of the existing one is > 1.

I guess that my idea of "temp" includes not holding on to ref counts for things but just turn it and burn it.

Btw, any time you find yourself wanting access to the ref count of an object, you are probably about to make a serious programming mistake. ;-)

[sarcasm]Aw, you mean implementing "weak references" by simply decrementing the refcount is a bad idea? Who would have thought.... [/sarcasm]

Just as a word of precaution to anyone, don't use the CFDelegate plugin from TooMuchSpace. It's extremely, extremely evil. It "implements" "weak references" by simply returning the object with its refcount decremented by one! This means you'll get all kinds of nasty crashes -- not exceptions, application crashes. And the cause won't be obvious, it'll crash in really random places....

Also the "PerformMethod" function in the plugin is dangerous. The author only planned on it working with objects -- trying to pass an integer and such will make your application crash.

Ok, now that was a tangent.

It may not be a matter of holding the reference outside the scope of a particular call. So, I may want to do something like:

dim b1, b2 as Picture

b1 = Buffer(10,10)

b2 = Buffer(10,10)
b2.graphics.DrawPicture(b1,...)

It's not clear that this would be a bug, since it is not clear there can be only one buffer. It seems like guarding against that would be a useful instance of knowing a refcount - or is there a better way? One could always argue that memory is cheap and caching is a form of optimization best left until a specific performance problem is noticed. But I'm sure we can get the opposite position argued pretty darned fast...

You can safely assume that you will never be able to query or modify the refcount of a REALbasic object, in case that helps guide your design thinking at all.

Well, I can already modify the refcount:

foo = new Blah
foo = nil

Modified! As for querying, can't plug-ins do that? I might be wrong, but I thought it was possible...

Well, sure, but that's indirect; the existence of a reference count is an internal implementation detail. I'm sure it's possible for plugins to do all kinds of hackish and unlikely feats, but direct access to the reference count is not and never will be part of the official API.

Hmm... I think the plugin SDK provides direct access to increment and decrement lock counts on objects, and this is part of the public, published programming interface. So the existence of a refcount is not just an internal implementation detail. And it's behavior is also documented (for instance, that an object is deleted when the refcount hits 0). In fact, this behavior changed once (briefly) until RS was forced to restore the old behavior since so much code relied on it.

It is true that plugins can lock and unlock objects directly, but plugins are a different world than RB code, and in RB code there is no such thing as a reference count. This is an important distinction, because I'd like to take another stab at improving the memory management system someday, and in order to do that I need to make sure that the memory management behavior remains at least somewhat abstract.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.