Note: Wordpress likes to convert my < > inside [ code ] blocks to to &amp;gt; and &amp;lt; so sorry about the formatting

After Beazley’s talk at PyCon "Understanding the Python GIL" I released I had never done any work that released the GIL, spawned threads, did some work, and then restored the GIL. So I wanted to see if I could so something like that with Boost::Python and Boost::Thread and the type of performance I’d get from it with an empty while loop as the baseline. So I hacked up some quick and dirty C++ code and quick bit of runable Python to test out the resulting module and away I went. Below are the code snippets, links to bitbucket, and the results of the Python runable.

#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/python.hpp>

class ScopedGILRelease {
public:
	inline ScopedGILRelease() { m_thread_state = PyEval_SaveThread(); }
	inline ~ScopedGILRelease() { PyEval_RestoreThread(m_thread_state); m_thread_state = NULL; }
private:
	PyThreadState* m_thread_state;
};

void loop(long count)
{
	while (count != 0) {
		count -= 1;
	}
	return;
}

void nogil(int threads, long count)
{
	if (threads <= 0 || count <= 0)
		return;

	ScopedGILRelease release_gil = ScopedGILRelease();
	long thread_count = (long)ceil(count / threads);

	std::vector<boost::shared_ptr<boost::thread> > v_threads;
	for (int i=0; i != threads; i++) {
		boost::shared_ptr<boost::thread> m_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(loop,thread_count)));
		v_threads.push_back(m_thread);
	}

	for (int i=0; i != v_threads.size(); i++)
		v_threads[i]->join();

	return;
}

BOOST_PYTHON_MODULE(nogil)
{
	using namespace boost::python;
	def("nogil", nogil);
}

Then I used the following Python script to run some quick tests.

import time
import nogil

def timer(func):
	def wrapper(*arg):
		t1 = time.time()
		func(*arg)
		t2 = time.time()
		print "%s took %0.3f ms" % (func.func_name, (t2-t1)*1000.0)
	return wrapper

@timer
def loopone():
	count = 5000000
	while count != 0:
		count -= 1

@timer
def looptwo():
	count = 5000000
	nogil.nogil(1,count)

@timer
def loopthree():
	count = 5000000
	nogil.nogil(2,count)

@timer
def loopfour():
	count = 5000000
	nogil.nogil(4,count)

@timer
def loopfive():
	count = 5000000
	nogil.nogil(6,count)

def main():
	loopone()
	looptwo()
	loopthree()
	loopfour()
	loopfive()

if __name__ == '__main__':
	main()

The results I got were quite interesting and very consistent on my MacBook Pro. I ran the script about 1,000 times and got roughly the same results every time.

loopone took 364.159 ms (pure python)
looptwo took 15.295 ms (c++, no GIL, single thread)
loopthree took 7.763 ms (c++, no GIL, two threads)
loopfour took 8.119 ms (c++, no GIL, four threads)
loopfive took 11.102 ms (c++, no GIL, six threads)

Anyway, that’s all really. Nothing profound here, no super insightful ending. Just hey look and stuff is faster and I might use this. All the code for this is available in my bitbucket repo. http://bitbucket.org/wwitzel3/code/src/tip/nogil/

You will require Boost Library including Boost Python and Boost Thread as well as Python libraries and includes to build this. For boost, bjam –with-python –with-thread variant=release toolset=gcc is all I did on my Mac. Then I added the resulting lib’s as Framework dependencies in Xcode along with the Python.framework.

PyCon 2010 this year for me has come and gone. This year was just as good as ever.

My wife and I drove up from Florida this year. It was a 5-hour drive and was actually pretty pleasant, considering she drove and I slept for initial and the return trip. I’m pretty much a horrible person to spend more than 2-hours in a car with anyway so it is much better if I sleep the whole time.

The location in Downtown Atlanta was great. Lots of bars, restaurants, and nightlife to choose from when the con events started to die down. Though the fact there was a liquor store across the street from the Hyatt pretty much meant that the con never died down. Though I had friends in Chicago who took us for nights on the town and out and about in the city, this location was much better overall for the rest of the attendees if you ask me.

The best place if you ask me was this 24/7 diner called the Landmark Diner. Great American style diner food along side some greek classics. It was tops on my list for breakfast in the morning and for that after hours drunken feast. In my 5-days in Atlanta we went here 4 times. I highly recommend it if you are ever in the city. It is on the corner of Forsyth and Luckie in Downtown.

The talks I went to were good. The open spaces I attended were good. The sprints I attended were good. Not much more to say really. You can find plenty of people who are more picky about the specifics than me so I’ll leave it at that. I had a great time all around with con. Everything was well organized and the efforts of the committee, and all the volunteers was impressive. I volunteered this year as Session Chair for some talks so if you go watch some videos you’ll see me introducing some people.

I met a ton of people and had a lot of hallway talks and late night talks about everything ranging from Python to politics. It is always great fun and I will repeat what many others have said before. Don’t be shy and don’t be afraid to skip and an official talk and join a hallway talk instead, they can be great. Oh also, I am stealing Jack Diederich’s (first heard from) idea for the Lunch Session next PyCon. Find a table with no one you know and sit at it. I love that idea.

I had some very late nights and some excellent times and I met a ton of great people. I’d like to thank some people in no particular order. CCP guys, Chicago Python guys, Jack Diederich, Jakub Vysoky, Travis Cline, Michael Trier

Looking forward to next year!

I had a lot of fun attending last year and I didn’t want to miss this year, specially considering I’m exploring my options with work at them moment and I’ve been told PyCon is a great place for that.

So I officially took care of everything I needed to today. I’ll be attending PyCon in Atlanta this year from the 19th thru the 23rd. I’ll be staying at the Ellis, mainly because it was a $500 savings over staying at the Hyatt Regency (being a AAA member paid off finally) and it is only a 2 city block walk to the main venue.

I’ll be attending 2-days of the sprints this year and I’m really looking forward those. Living so close in Florida I’ll be driving up the 5 hours to Atlanta instead of flying.

If anyone else is staying at the Ellis drop me an email we can breakfast together before our morning walk to the Hyatt.

Today I was having a chat today about Pylons vs. Django and for the most part it was pretty diplomatic. We got to talking about the Admin interface the Django has. Which you don’t have to do any extra boiler plate for, it is just there for you. With Pylons you have to use something like FormAlchemy or use Turbogears to get a similar style admin interface for your models and data.

Since we were sitting at a computer, I went ahead brought up a quick project and did a little demo of the paster shell. Sure, it involves typing and it isn’t as pretty or “fast” as an admin panel, but he didn’t even know it existed. One of the common things he mentioned was, “if I want to change the menus that are dynamically defined” or “if a username needs to be changed” .. and the application itself doesn’t have a custom admin panel, with Pylons he had to do raw SQL.

$paster shell pylons_config.ini

All objects from demo.lib.base are available
Additional Objects:
   mapper     -  Routes mapper object
   wsgiapp    -  This project's WSGI App instance
   app        -  paste.fixture wrapped around wsgiapp

>>> error_user = meta.Session.query(model.User).filter_by(username='wwitzel 3').one()
>>> # nice thing about this, is you also will get exceptions throw if more than one record exists
>>> error_user.username
u'wwitzel 3'
>>> error_user.username = 'wwitzel3'
>>> meta.Session.commit()
>>> menu_typo = meta.Session.query(model.Menu).filter_by(id=1).one()
>>> menu_typo.value
u'Abuot'
>>> menu_typo.value = 'About'
>>> meta.Session.commit()

So that is a very simple example of how one would use the paster shell to update some bad data in the database while ensuring integrity of your custom model and extension code. After I showed this to my friend he wasn’t as concerned about the lack of a web interface for administration within Pylons.

So I’m currently looking for new work and I’ve defined my list of items that are high priority to me. I figured I’d list them here and then break each down in to a little detail. Mainly because I’m up late at a stopping point in some code and haven’t updated my blog in forever.

  • Refreshing
  • Excitement
  • Vision
  • Caring

Refreshing

What do I mean by refreshing?  I mean a company that isn’t doing what everyone else. Something that isn’t YAIC (Yet Another Internet Company). For me, this can really mean two things though. It could also mean a company that produces software for an industry I’ve never worked in before, but ideally it is a company doing something new, innovative, and refreshing. At the end of the day, writing software for them makes you go “Ahhhhhhhhhh”.

Excitement

I want everyone in the company I am working for to be jacked about working there. I want people to be excited about the products. Even if they are boring everyday products. If everyone there is excited about them and cares about them it promotes a much better work environment and in my experience a higher quality product.

Vision

Here’s where we are. Here’s where we are going. Here is how WE are gonna do it. This seems as one of those things that is so easily over looked once you’re out of lets keep this startup from dying working 100 hours a week mode, but even for established companies this is so important. Without a vision your company will eventually end up stuck in the mud.

Caring

This is more in the human respect. We are sometimes at work more than we are at home. This is especially the case with small companies and start-ups (and even some big ones). Companies that care, have employees that care. Treating employees like cattle will only result in employees treating the company like a feed station. Every place I’ve worked that did mandatory start / end times or mandatory OT always had issues getting coverage and had huge turn over rates compared to flex time locations with resources for employees to relax, take breaks, and feel cared about.

I asked the question I Stackoverflow and maybe it was too generic for the site, since it just got trolled with “Google keyword” by some d-bag. So I deleted it and figured I’d throw it up on my blog a see about getting some feedback from the people who read this pile about. The reason I ask this is mainly because I am preparing to do some updated screencasts for Pylons.

I’ve seen multiple ways referenced in official docs and I have done it a few different ways myself. I am using Pylons and I am curious what the best practices are for this common scenario?

I have used something similar to this for auto-magically making the conversion happen.

# The auto-magic version
# I pulled this off a blog, forget the source.
def _sa_to_dict(obj):
    for item in obj.__dict__.items():
        if item[0][0] is '_':
            continue
        if isinstance(item[1], str):
            yield [item[0], item[1].decode()]
        else:
            yield item

def json(obj):
    if isinstance(obj, list):
        return dumps(map(dict, map(_sa_to_dict, obj)))
    else:
        return dumps(dict(_sa_to_dict(obj)))

# here is the controller
@jsonify
def index(self, format='html'):
    templates = Session.query(Template).all()
    if format == 'json':
        return json(templates)

I have also done the version where you use the jsonify decorator and build your dictionary manually, something like this, which is ok if I need to define some custom behavior for my JSON, but as the default behavior seems excessive.

@jsonify
def index(self, format='html'):
    if format == 'json':
        q = Session.query
        templates = [{'id': t.id,
                      'title': t.title,
                      'body': t.body} for t in q(Template)]
        return templates

I’ve also created an inherited SA class which defines a json method and have used that on all my objects to convert them to JSON. Similar to the the fedora extensions.

Maybe I missed some obviously library out there or some obvious helper in the Pylons packages, but I feel like this is a very common task being done a dozen different ways between docs, source, and my own personal projects. Curious what others are doing / using.

I am sure everyone else who lives in the world of jQuery knows this, so this is more here for my own future reference and avoiding and more wasting of time, but if you are going to us $.getJSON helper in jQuery, append a time stamp to it to prevent odd caching behavior in IE. See the example below.


$.getJSON("/story/story_id.php?_="+(new Date().getTime()), function(json) {
$('#next_story_id').html('S' + json.next_story_id);
});

This might not be the best way to do it and really, this is good practice for all dynamic requests to avoid caching issues from the browser and the server. Chalk this up as a good learning experience that sucked 30 minutes of my life. I hate front end stuff.

unrelated-picture

Sometimes putting into words the practices you use can expose obvious flaws where you need improvements and provide a starting point for introducing new practices in to your development. Analogies are often used to express sometimes foreign, sometimes complex ideas by bringing them in to a realm that is familiar.

Idea
My development is fueled with an idea. The idea sometimes bad, sometimes good, and rarely great, but nonetheless this is where I start. The idea usually stems from a problem. I want to be able to do Foo or I’d really like if Bar was able to do this.

What ever it maybe, I think it is important to take the time to outline your idea. Give yourself some initial requirements. Give yourself some structure to build on. You need a solid foundation for a project to be seen to completion and even with that, most fail to make it.

Now don’t get me wrong, I am not saying you need a full set of business requirements with risk analysis, input from legal, hiring a marketing firm to ensure there is sufficient market share to capture to justify the risk of development. I am just saying you need to have some kind of outline, some set of initial requirements, your motivation. They are easy to create and it only takes a minute.

Once it makes it past the idea stage, it means I’ve written down on paper. I’ve created a loose set of requirements for the project and I still think it is a decent enough idea to continue.

Design
The design process is unique beast. There is plenty of reading material out there about design and about architecting software. I am by no means a great architect. I know enough UML to not be confused by it, but I couldn’t punch my way out of a wet Visio box.

My approach to design is brief at best. I hop a plane to 30,000 ft and look around. I make some notes of that obvious things I see. Oh look a Factory Pattern, oh look a white fluffy Strategy pattern, hey that skyscrapper looks a lot like a Reactor pattern and that lake looks like a Facade. I like patterns, even though some people seem to think they hinder innovation and developers coming up with new awesomeness. I make some notes and polish my lead balls to ensure my development compass points North. That is it.

As a rule of thumb, I try to spend no more than a day on this phase. Depending on the scope of the project and the requirements you may require more or less time, but that is really up to your gut. As soon as you feel comfortable laying down code, start laying down code.

plants-tell-me-fings

Now The Analogy - Growing Software.
I am a giant fan boi when it comes to test driven and agile processes, I mix and match the different processes to meet my needs. My favorite anology I use to describe my process of what I like to call organic development, involves growing plants. I am sure the term organic development already exists and means something completely different, but I don’t care, I like it for this.

  • Idea – Decide you want to plant something and read up on what you’re planting.
  • Design – Sun? Shade? Raised bed?
  • Coding – Watering, fertilizing, repotting and transplanting.

So with the idea you read about what you are planting. You look at maybe some other people who have planted the same type of plants and read on their experiences if they are available.

Now the design. You pick out your pots or bed type. Decide if you are gonna use natural light, artificial light, how much water and they type of delivery mechanism? I hear they have these cool water globes now!

Now you can plant the seed. You water and weed and as your plant grows you prune, stake in supports, and continue to care for it until it comes to bare. With the proper care and handling you can produce a healthy, beautiful, low maintenance plant.

Keeping with this software is a plant analogy, somethings to watch out for. Water too much you run the risk of killing your plant (developer burn out). Prune too much and you can kill it (premature optimization). Basically in the early stages of a plants life mistakes can easily kill it I think this is very similar to software.

As your plant takes root it becomes easier and easier to maintain. Things like transplanting, ripping a plant out to the roots and replanting in a new bed are risky, but if done right, can produce a larger, healthier plant. Like software, sometimes completely gutting a prototype might be the right thing to do, but you increase the risk of killing the project.

But also plants, like software, can be very forgiving as long as you catch the the fact early that you are giving your plant too much or too little of water, pruning, fertilizer, soil to grow in, etc… you should be able to salvage it. Though it will take more work and time, with extended care an over or under watered plant can be saved from the brink of death with a little time investment and care. But sometimes there is nothing you can do, like an over pruned Bonsai tree, once the damage is done, even if you continue to grow your plant, it will never feel right for many many years.

So anyway, that is might crazy, abrupt, all over the place abstract take on software. What’s yours?

On a side note, an email commenter Linda requested I have more pictures in my posts so this one is for you Linda.

EDIT: Fixed the strong tags. WP decided to do something weird with the formatting. Also fixed some typo’s.

There is an on going discussion at the office with a team member who refuses to use dynamic languages. Claiming that most of his errors are typographical errors and they are caught by the compiler. So for him, since these errors are not caught until runtime, he throws and entire group of languages out the window. He also claims that to ensure that same level of checking with a dynamic language you would have to create more unit tests than normal to prevent introducing unhandled runtime exceptions.

So I decided to do a little test over the weekend. I created a very simple Number class in Python and C++. Using the exact same TDD development process, I implemented some very basic operations including division, addition, subtraction, etc… I ended up with 12 tests. The exact same tests for both the C++ and Python implementation resulting in 100% of the executation path being covered. I decided that the compliation (in case of C++) and passing of the tests determined a success.

Then went back and inserted common typographical errors. Mistypes, extra = signs, not enough = signs, miseplled_varaibles, etc… The end result was I was unable to get my unit tests passing while introducing syntax that would induce an unhandled runtime exception in Python. Granted, in C++ the compiler did catch a lot of things for me, but the point here is I didn’t have to create any extra tests to ensure that same level of confidence in my Python code.

I want a new theme for my blog. This site runs Wordpress 2.7. So please link your recommendations in the comments. I’d like something simple and clean but a little more pleasing to the eye than this current theme.

I’ve been flipping through the different ones on the Wordpress site, but there is so many and I have no zero skills when it comes to what looks good and what doesn’t; I like Christmas colors if that tells you anything.