Monday, 28 February 2011

Why more memory can speed your computer up

Firstly, we need to be clear. The memory I am talking about is called RAM, not the 'memory' which exists on your hard disk to store programs and files in. They are measured in the same way but RAM is more expensive and usually smaller, for instance 4 gigabytes (Gb - approx 4 billion bytes) whereas a hard disk might be 240Gb or larger.
The point here is that a hard disk although cheaper is much slower because it contains moving parts, literally solid disks of data being read by a moving head. RAM is electronic and very fast.
When you run programs on your PC, they will require a certain amount of program memory and this will be allocated from your PC RAM. However, if you do not have enough RAM (if you are already running too many programs and/or you don't have much RAM in the first place) then the computer will still allocate the memory but it will put it on the hard disk instead - a bit like putting your possessions into storage when you run out of room in your house.
The data can be moved into and out of this 'virtual memory' but like the storage unit, it takes much longer to send it and get it back. This makes the computer slower because programs wait for the memory contents to come back before they can carry on. You can tell this is happening because the hard disk will spend lots of time spinning.
As time goes on, programs require more and more memory, partly because they do more things and partly because people tend not to worry about memory requirements when writing software.
The easy answer when this happens is simply to buy more memory for your PC. You can either search a site like crucial.com for what memory your PC takes or take the model number and make to a shop where they can check for you. Most memory is fairly standard and you should be able to get at least 4 Gb depending on whether your computer can access this much (after a while, there are too many spare rooms in the house and you have to go back to using storage). For most people using non-specialised software, this is more than enough memory to get good performance.
1Gb will cost around £15/$25 in the UK so it is not much money to improve your PC.
If your PC is ancient, you are probably better off buying a newer basic model for a couple of hundred pounds then all the components will be improved.

Saturday, 12 February 2011

CJuiAutoComplete Example

I've started using Yii and am very impressed with it from an ease-of-use and installation as well as certain areas that have been thought about properly and implemented well. I wanted an auto complete box on a view and had a quick look at the documentation on the Yii site but it had no worked examples and I was new to Yii and didn't understand how it connected up HTML, jQuery and the php code. I have now got something working which I would like to share for others use. Firstly, here is how I declare my Yii php code for the control:
<?php $this->widget('zii.widgets.jui.CJuiAutoComplete', array(
     'name'=>'churchac',
     'source'=>CController::createUrl('user/churchsearch'),
     'options'=>array(
         'minLength'=>'2',
         'focus'=>'js:function( event, ui ) {
          $( "#churchac" ).val( ui.item.label );
              return false;
         }',
         'select'=>'js:function( event, ui ) {$("#churchac").val( ui.item.label );$("#User_church").val( ui.item.value ); return false; }',
     ),
     'htmlOptions'=>array(
         'style'=>'height:20px;'
     ),
)); ?>

A few points to note here. Firstly I have added function handlers for select and focus to override the default behaviour. This is because I want to display a church name to the user but store the database id in a hidden field which is linked to the model for when this view is saved. In my case I have simply updated the autocomplete box (#churchac) and the hidden field (#User_church). Also note the "js:" at the start of the strings for these handlers which stops Yii from escaping the quotes around the jQuery selector names on the HTML.
Next up is the controller function which looks like this:
public function actionchurchsearch($term)
{
    $sql = 'SELECT columns FROM tables LEFT JOIN etc..';
    $keywords = explode(',',$term);
    $sql = $sql.' WHERE name_1 LIKE \'%'.trim($keywords[0]).'%\'';    // Must be at least 1
    if ( count($keywords) >= 2 )
    {
        $sql = $sql.' AND city LIKE \'%'.trim($keywords[1]).'%\'';
    }
    if ( count($keywords) >= 3 )
    {
        $sql = $sql.' AND name_2 LIKE \'%'.trim($keywords[2]).'%\'';
    }
    $sql = $sql.' LIMIT 10';
    $schema=Yii::app()->db->schema;
    $builder=$schema->commandBuilder;
    $command = $builder->createSqlCommand($sql);
    echo json_encode( $command->queryAll());
}

A few more notes here. The function needs the word "action" added to the front as with other actions. You must also allow access to it in the accessRules() function of your controller. It takes a single parameter which is the search text that the user has typed in. In my case, I allow a multi-part search so I split the string up into separate elements and build a standard SQL statement to find the results. I have used the more basic CDbCommandBuilder class since the CDbCriteria is very much geared around retrieving data to populate models with but in my case, I just want simple search data to use in the autocomplete. Also note, you should provide an alias for the columns that you want to display (called label) and to select (called value). You can add other fields but you would need to explicitly use these if required. Note that I don't return the data but echo it to the response since this is an Ajax function. I use a built-in php helper function called json_encode and this ensures that the data is in a format that is usable by the auto-complete control (obviously you can't just echo a php array and expect javascript to handle it).
As a side note, remember this function can be called many times over a very short period so you might need to ensure that it works efficiently and caches search terms if appropriate to avoid frequent database queries. Also, see my newer post on customising the return data: