Wednesday, December 29, 2004

Backup entire blog

One of Blogger's FAQs is "How do I create a backup of my entire blog?" However, that looked too complicated to be of any use. Here is what I do:

cd blogbackup
wget --timestamping --recursive

wget is available for linux/unix/cygwin and even windows.

Tuesday, December 28, 2004

functor vs function object

It appears that I have been using the term "functor" incorrectly. This is from an email posted on Boost-users list by Jeff Flinn, he quotes a letter to the editor of C++ Report:
Here's the low-down, to which any mathematician would attest:

A function is a transformation that maps an element to an element.
A functional is a transformation that maps a function to an element.
A functor is a transformation that maps a function to a function. (The truth functions in propositional logic are also sometimes called functors.)

Simple, isn't it? We seem to use the first one correctly, but not the other two. What people commonly call a functor (thanks to Dr. Coplien, shame!) is what the C++ Standard calls a function object. It seems some people like to use "functional" to mean the same thing. Shame again! A function object is simply that, an instance of a class that behaves like a function by virtue of its operator(). Some function objects, like bind2nd, do behave like functors, in that they take a function object as input and return a function object as output. Only these deserve the functor moniker, although you may prefer "function object adaptor" (or is it spelled "adapter" :-) , as denoted in the C++ Standard.


I just received a new machine at work (AMD Athlon 64 3200+ 2.2 GHz 1 GB RAM). Its main purpose is to be a Windows build machine for my current project, but I'm also using it for my day to day development work as well, because it is really fast.

I've become accustomed to using two monitors. My laptop and a 21 in. Sony CRT. I love high resolution so I run my laptop at 1600x1200 and the CRT at 1920x1440. However, the new machine put me in a dilemma: how do I use the new machine but still have two monitors.

First thing I tried was using Window's Remote Desktop to connect to the new machine from my laptop. However, Remote Desktop is limited to 1600x1200 and I wanted 1920x1440. So next I tried various versions of VNC (UltraVNC, TightVNC-unstable, RealVNC), but they where all too slow at 1920x1440.

Jason suggested that I try Win2VNC.

What does Win2VNC do? From the website: "This program will let you use two screens on two different computers as if they were connected to the same computer." Run a version of VNC server on one machine and run Win2VNC as a client on another. When the mouse moves off one screen it appears on the other allowing you to control both machines using the same keyboard and mouse. You see the updates on the actual machine's display. Its kind of like having a KVM switch that is triggered by the mouse moving off the screen.

The only problem that I found was that the mouse wheel didn't work. However, using this version of Win2VNC fixes that problem.

Of course, now I have two machines capable of running two monitors. All I need now is some more monitors. :)

Friday, December 24, 2004

Merry Christmas

Don't forget to set aside a silent moment to reflect on God's gift to us. Have a merry Christmas and may God bless you and your family.

Condition variable spurious wakeup

Weiqi's year end review mentioned his spurious wakeup blog entry that he wrote in April. Jonathan and I were talking about this a few weeks back. I was reviewing his code and commented on the importance of checking your condition when you wakeup because of spurious wakeups. So if you are using ACE condition variable you need to make sure you do something like:

ACE_Guard<ACE_Thread_Mutex> guard(mutex_);
while (value != expected_value)

The cool thing is that boost's condition variable wait() method takes a predicate functor to handle spurious wakeup.

struct CompareVariable {
bool operator()() const {
return value_ != expected_value_;
int value_, expected_value_;
} pred;

boost::mutex::scoped_lock guard(mutex_);
condition.wait(guard, pred);

   condition.wait(guard, pred);
above is equivalent to
   while (!pred())wait(lock);

Tuesday, December 21, 2004

Turning on ACE debugging

I was trying to figure out how to turn on ACE debugging the other day. I didn't have my ACE Programmer's Guide with me and I wasn't finding it via Google. All the examples I found talked about how to change code to enable ACE debug statements, but I knew that it could be done through configuration. Turns out you need the following in your svc.conf file:

dynamic Logger Service_Object* ACE:_make_ACE_Logging_Strategy() "-s log.txt -f STDOUT|STDERR|OSTREAM|VERBOSE -p DEBUG"

This is discussed in section 3.8 (page 73) of ACE Programmer Guide and at this link: Logging Strategy Service

Monday, December 20, 2004

C++ Convert int to string

On my current project at work, we have been focusing on speed. Its interesting to think about how many microseconds (or nanoseconds) it takes to do something. I hope to post over the next few weeks some performance comparisons between various techniques in C++.

My laptop which I'll be running the tests on is a Mobile Intel Pentium 4M 2200 MHz with 768 MB DDR SDRAM. I'll be compiling with Microsoft Visual C++ 7.1 in release mode. The tests are simple iteration tests running the same code over and over again a 1000 times. I know that this is not representative of real performance do to caching affects, but even this simple testing can be eye opening.

Today lets look at boost::lexical_cast. We use boost and ACE on our current project. lexical_cast is a way of converting between strings and other types (actually it is a generic way of converting to/from more than just strings). So if I wanted to convert 23 to "23" I can do this:

std::string twentythree = boost::lexical_cast(23);

If I do this on my laptop it runs in about 7 microseconds. Not too bad. However, if I use a C approach and do the following:

char buf[20];
ACE_OS::sprintf(buf, "%d", 23);

It runs in 0.3 microseconds, which, I think you would agree, is better.

The lexical_cast is safer and more general but is it worth the difference? I would say it depends.

So why is lexical_cast so much slower? Well, its because it uses std::stringstream. Take a look at the following:

std::stringstream ss;
ss << 23;

The above takes 6.7 microseconds, which is clearly most of the effort of lexical_cast.

Friday, December 10, 2004

Google Suggest

Jonathan just pointed out Google's latest: Google Suggest.
"As you type your search, Google offers keyword suggestions in real time"

Try it out, I think you will like it...

Thursday, December 09, 2004

Rob Smith Blog

In case you didn't get the email, Rob Smith started a blog. Rob is a up and coming star at OCI. It will be interesting to see what he has to say.

Saturday, December 04, 2004

Beware of Methodologies

I just read again Joel's Big Macs vs. The Naked Chef article. I agree completely with Joel's commentary, but I wonder if it is because I want so much to agree with the idea that highly skilled individuals can never be replaced.

Let me think...

Yep, that does sound right. This is why I believe OCI has been successful. Higher a bunch of really smart people, and run with it.

Friday, December 03, 2004

Toyota's mobility concepts

I saw the following on Gizmodo. The following link has some very interesting pages on Toyota's concept "Robots". It doesn't give a top speed for the car like "robot", but does have some interesting descriptions.

toyota_iwalk_iunit.jpg image

Google index updated

Google has updated their index so that the first link for "Kevin Heifner" now points to this blog instead of Providence Christian Academy (Classical Christian School in St. Louis). My employer OCI still shows up below Providence School, but its nice that "Kevin Heifner" now goes to this blog.


Weiqi pointed out SWIG (Simplified Wrapper and Interface Generator) to me today.

What is SWIG?

SWIG is a code generation tool that connects programs written in C and C++ with a variety of other programming languages including Perl, Python, Tcl/Tk, Ruby, C#, Common Lisp (Allegro CL), Java, Modula-3, OCAML and various implementations of Scheme. SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG may be freely used, distributed, and modified for commercial and non-commercial use.

Looks very interesting!