Archive for December, 2005

December 11th 2005

A Productive Work Environment

I’m not an expert on the subject of making a work environment as good as it can be, but here’s a few things I’ve observed, partaken in, or believe are good ideas. These are all from a programmer’s perspective.

  • Influence: Most engineers I think want to know that their opinions matter. I think this is much easier to achieve in a smaller company, but for larger companies it comes down to this: the more layers of management between the programmer and the people who make the decisions, the worse off that engineer is in feeling that he’s making a difference.
  • Regular Chances to be creative: Let’s face it, being told what to do every second is boring. Sure, some projects are fun to work on, but others you just don’t want to face. However, you do it anyways. During those times, the chance to be creative is more than welcome. Google does it with 20% time. Basically, 20% of your work week (unless you’re in a crunch time where you need to finish something up as soon as physically possible) is allowed to be on a project of whatever you want to work on. Not only that, but these projects also often turn into full projects at Google. Google News, Orkut, Adsense for content, and Google Suggest are all products of this time. Imagine the feeling you would have if not only you were allowed to work on something that was fun for you, but ended up getting a budget and a team to help you finish it up.
  • Occasional Code Fests: While regular creativity chances can be great, it’s often done in seclusion. Recently, I read about Yahoo! having a “Hack Day,” where everyone who wanted to participate could “hack” on something the entire day, in teams if desired, to showcase the results at the end of the day. Another fun thing that was very productive several years back for REAL Software was a week where the most popular bugs that could be fixed within a day were written up on a large board, and everyone picked one off, fixed it, crossed it out, and moved on. While I wasn’t there at the time, I hear it was great to see the list get shorter and shorter. Not only that, it benefited the customers in a great way.
  • Flexible scheduling: I can’t count the number of times that I stayed up late at home fixing a bug, replying to emails, or solving a problem with something that stumped me at work earlier that day. The greatest feeling is the ability to show up late the next day, and not have any questions asked. The last thing I would want is to stay up until 1 in the morning coding something that I was “on a roll” and “very close” to finishing, and feel like I had to be there at 9:00 AM sharp.

Luckily, I’m very happy with my job, and it’s because of the above things. This isn’t actually inspired by me wanting to change my current environment — it was inspired by reading about Yahoo!’s “Hack Day” earlier in the week. I then started thinking about how great of an idea that was, and why I liked my job so much. Aside from the fact that I have coworkers that I really enjoy working with, it’s the above reasons that keep me happy as a programmer.

What things make you like or hate your job? Anything that you feel should be added to the list?

4 Comments »

December 8th 2005

Holiday Treat

Well, it’s been over a month, and I wanted to update. As you can see above, I definitely wasn’t just relaxing. Those are my first attempt at creating my mother’s famous cinnamon rolls, and they turned out pretty dang good. They took several hours to make from scratch, but it was well worth the effort to have these fresh out of the oven on Thanksgiving morning.

I actually was out of town, but still working for the majority of it, for two weeks during November — partially a work related trip to begin with, but the second week was to visit my girlfriend and her family. On top of that, my programming efforts have centered pretty much solely on work related items, including endeavours outside of work. Some of it is relating to the next release of REALbasic (which I can’t talk about :)), some of it is related to a much larger, future project (which I really can’t talk about :D).

But alas, the great thing about working with REALbasic all the time is that, even when working on new releases and secret projects, I still will come up with a good tip or two to write about. So, here’s my holiday treat to my readers: a sweet (quite literally if you look at the picture above) update with lots of good information.

Tip: The Location Field
This is a REALbasic 2005 tip. If you’ve noticed, the toolbar has a location field, similar to a browser’s location field. If you know exactly where you want to go, you should use this. Why, you ask? Let’s say you have a complex hierarchy of folders (for us, that’s the IDE project, with now nearly 140,000 lines of code). One example is that I always forget where DebuggerUI is. It’s partly because it moved a couple months back, and I don’t go to it that often. Well, in 2005 to get to debugger UI, I don’t have to traverse through folders (User Interface/Execution/Debugger/DebuggerUI). Instead, I simply press Command-L (or Ctrl-L) and type DebuggerUI — which will autocomplete for me. Pressing return, two things happen. First, the folders necessary will be expanded to reveal and highlight DebuggerUI in the project tab, and second, the DebuggerUI will open for me.

That’s great, but what about jumping to a specific method? Well, let’s say I was interested in DebuggerUI’s method “RaiseTargetApp”. In the location field, I would type DebuggerUI.RaiseTargetApp, and it would open DebuggerUI for me, switch to the code editor, and highlight the RaiseTargetApp method.

This even works for computed properties. Simply add “.Get” or “.Set” to jump to a specific accessor inside of a computed property.

For us old-schoolers, it may be difficult to remember to do this rather than jump through the hoops of our folder hierarchy. However, I urge you to try it out, and take a stab at shaking the old habit. Its beginning to become part of my workflow, and it’s definitely a huge timesaver.

How to Update UI from a thread
This is a popular topic. What is the best way to update your UI from a thread? There’s several trains of thought, but I’m here to give you the definitive answer. Ok, maybe not definitive, but it’s a great scheme that will work great on all platforms, and not slow down your thread code unnecessarily.

The basic problem is this. You have some computational loop such as:

Sub Run
While ubound( itemsLeft ) >= 0
itemsLeft.Pop.ComputeResult
Wend
End Sub

You’ve done the first step: abstracted the code into a thread. But, in the process, you’ve lost your progress bar. So, you decide to hard-code it:

Sub Run
While ubound( itemsLeft ) >= 0
itemsLeft.Pop.ComputeResult
Window1.ProgressBar1.Value = (TotalItems - ubound( itemsLeft ) + 1) / TotalItems * 100
Wend
End Sub

But you noticed it slowed down your code tremendously. Why is that? Well, every time you process one item, you tell the progress bar it has a new value. Since the code is threaded, it will eventually yield time back to the main thread, which will then promptly decide it should redraw the scrollbar. This isn’t ideal, because you’re causing too many refreshes. The first instinct is to start writing code that will limit it to “x” iterations. This also isn’t ideal, because on faster computers, “x” iterations will take less time, and you’ll be faced with the same original problem. The last instinct is to make it based on time, and have the thread update the UI every “y” milliseconds. Again, this is less than ideal. While much better, you’re still making the thread decide when to update the UI, which might yield unoptimal performance on systems that sync updates with the beam of a monitor (OS X mainly, but more and more other operating systems are moving towards this model).

So, what’s a person to do? Here’s my three-step program to updating UI while performing a time-consuming task:

  1. Ensure that your code is run from a thread.
  2. Don’t let your thread talk to any UI. Instead, update properties on your thread.
  3. Let the UI ask the thread periodically (via a Timer) what the current status is.

This is a beneficial approach for several reasons:

  • Timer’s are invoked directly from the event loop, instead of from within your thread code. They are very low-overhead, and will not slow down your loop by checking the current Ticks() to see if you should update the UI.
  • This allows for better encapsulation. Instead of the Thread knowing it’s updating a ProgressBar or StaticText, you can redo your UI without the thread knowing that something changed.
  • You can easily turn on or turn off the timer based on whether or not the status has changed.

Let’s create a Thread class that we can reuse that will help encapsulate the logic.

Class ProgressThread
Inherits Thread
Event ProgressChanged()
Event RunThread()
Private timer As ProgressTimer
Dim PercentComplete As Integer
Dim StatusMessage As String
Sub Run() Handles Event
RunThread
timer = Nil
End Sub
Protected Sub UpdateProgress()
If timer Is Nil Then timer = New ProgressTimer( Self )
timer.Mode = 1
End Sub
Sub ProgressTimerAction()
ProgressChanged
End Sub
End Class

Class ProgressTimer
Inherits Timer
Dim thread As ProgressThread
Sub Constructor( t As ProgressThread)
thread = t
mode = 0
period = 500
End Sub
Sub Action() Handles Event
thread.ProgressTimerAction
End Sub
End Class

A few design notes: I created a circular reference between the thread and the timer. This was necessary, because the thread needs to update the timer, and the timer needs to be able to tell the Thread when it’s fired. The UpdateProgress method simply sets the mode to 1 on the timer. This will turn the timer on to fire once whenever we have a change in status. However, if 3000 changes in status come in before the period of the timer has expired, it will still only fire once. This is the goal: limit UI refreshes, so that the thread can run at maximum speed. Now, let’s subclass it and do something with it.

Class FileProcessor
Inherits ProgressThread
Dim filesToProcess() As FolderItem
Sub RunThread() Handles Event
Dim fileCount As Integer
fileCount = ubound( filesToProcess )
While ubound( filesToProcess ) >= 0
Dim currentFile As FolderItem
currentFile = filesToProces.Pop
StatusMessage = "Current file: " + currentFile.DisplayName
PercentComplete = (fileCount - ubound( filesToProcess )) / fileCount * 100
UpdateProgress
ProcessFile( filesToProcess.Pop )
Wend
End Sub
Private Sub ProcessFile( file As FolderItem )
// Do some processing
End Sub
End Class

That’s not too different, right? Well, it’s different enough to be beneficial. The thread no longer cares who does what with its progress information — it just focuses on getting the job done.

Sub ProgressChanged()
ProgressBar1.Value = fileProcessor1.PercentComplete
StatusText.Text = fileProcessor1.StatusText
End Sub

That’s all it takes. To invoke this thread, it only takes a couple of lines:

fileProcessor1.filesToProcess = someArrayOfFilesIGot
fileProcessor1.Run

This design does a great job of abstracting the logic to updating the UI regularly without slowing down your thread unnecessarily. Timers have very low overhead, and always fire from the main event loop. Despite the ProgressChanged event firing from the Thread’s namespace, the event is being invoked from the timer’s action event, which is always invoked from the main thread, inside of the main event loop.

Doing this will ensure that on all platforms, your UI gets updated regularly (but not too often), and doesn’t artificially cause slowdowns to your code.

7 Comments »