views:

136

answers:

1

Aight, basically, I have a database that looks like this:

id | parentid | type    | name
---------------------------------------------
 1 |   0      | heading | this is my heading
---------------------------------------------
 2 |   1      | child   | this is one of many child elements

I'm using Mako to go through that list of data and create nested UL's. It seems to work great... But I'm not sure if my code could be improved.

Here it is:

<%def name="getCategories(parentID)">

   ## This function creates the children LI for the main headings
   ## Parameters:
   ##    parentID - Integer - ID of the heading you want to get the children for

   <%
      categories = [x for x in c.headings if x.type == 'category' and x.parentid == parentID]
      categories.sort(key=lambda x: x.name)
   %>

   %for category in categories:
      <li>
         <ul>
            <li>${category.name.title()}</li>
            ${getSubCategories(category.id)}
         </ul>
      </li>
   %endfor

   <%def name="getSubCategories(parentID)">
      ## Get the subcategories for the parent category
      ##
      ## This could eventually turn into a recursive function to get further subcategories
      ## which is why it has it's own function rather than just having another for loop above
      ##
      ## Parameters: Same as above

      <%
         categories = [x for x in c.headings if x.type == 'category' and x.parentid == parentID]
         categories.sort(key=lambda x: x.name)
      %>

      %for category in categories:
         <ul>
            <li>${category.name.title()}</li>
         </ul>
      %endfor
   </%def>

</%def>

If you're wondering why I have two functions that produce the same output, it's because they don't. The nested UL's produced from getSubCategories() are styled differently (HTML) than those produced from getCategories().

Is this slow? Will it die under a heavy load? Could it be improved?

I'd appreciate your advice. Cheers.

+1  A: 

First, there is no way to know if it's going to die under a heavy load without testing it. The only way to anwser you question honestly is to profile your code. Only you can do it.

Now, nested relations are always slow, but you seem to use only 2 levels of nesting, therefor it's O(n^2), nothing that could kill remotely a server.

Some ways to improve it:

  • Remove this mix between code and markup. It really hard to read and probably as hard to debug. I know Mako is flexible enough to let you do that, but it's not because you can, that you should. Try some MVC.
  • If it reveals itself to be slow, then explore alternatives such as closure tables. But since you just display the tree, it may have no impact at all. You may at best speed up the sorting.
  • Talking about sorting, try to sort and filter categories when you query the database, instead of in the code. It's better than you for doing this things.
  • Or if you don't, at least make only one loop to generate both lists. The filtering is the same, no need to go trough all the items twice.
  • I guess your categories won't change at every page loads. Cache it.
e-satis