Nothing interesting has been happening lately. A few side projects that are neat, but other then that no new coding advancements. I was playing with memoization a bit. Of course, in my everyday job I have absolutely zero need for this. But maybe I will find something useful. I think that I could try to implement some advanced code techniques at work, but we would have to do things better first. Hundreds of different pages all using sql queries, no real structure. It gets mind bottling after awhile.
But anyways. To explore memoization, lets use my favorite advanced math algorithm interpreter, PHP.
The fibonacci:
| PHP | | copy code | | ? |
| 1 | function fib($c) { |
| 2 | if( $c == 0 ) return 0; |
| 3 | if( $c == 1 ) return 1; |
| 4 | return fib($c-2) + fib($c-1); |
| 5 | } |
Ok, so we have a nice recursive function to calculate the nth number in the fib sequence. Lets use it to calculate the 20th, 30th, and 40th numbers.
- Start
6765: Time: 0.012
832040: Time: 1.178
63245986: Time: 135.191
Whoa, so times really start to add up quick. But we have to calculate this number or we get fired(this makes as much sense as anything else I do so I’m going to stick with it) and we have to calculate it quickly! We can use memoization on this fib() function to speed up the calls. This means that we will cache results as we calculate them, and then if we try to calculate the same number, we will grab the result from cache instead of running all the calculations again. This works because the results for fib(x) are always the same. There is no user input, time values, or any other real world nonsense getting in the way. We are going to add a static array to the fib() function, and store/retrieve the results from that array. Here is the code:
| PHP | | copy code | | ? |
| 1 | function fib($c) { |
| 2 | static $map; |
| 3 | if( !is_array($map) ) $map = array(); |
| 4 | if( $c == 0 ) return 0; |
| 5 | if( $c == 1 ) return 1; |
| 6 | if( !isset($map[$c]) ) // Have we already calculated this? |
| 7 | $map[$c] = fib($c-2) + fib($c-1); |
| 8 | return $map[$c]; |
| 9 | } |
We have a check to see if the request value has already been calculated. If not, we calculate it and store it. Then we return the stored version. This should speed things up. Lets run it again:
-
Start
6765: 0.001
832040: 0.002
102334155: 0.002
That is a serious improvement. It should be, we are only making 40 calls instead of the previous huge number. Now I just need to find a situation where this may be useful in my day to day programming.
What about a new language, C#? Lets run the same code again:
| C# | | copy code | | ? |
| 01 | static int fib(int x) |
| 02 | { |
| 03 | if (x < 2) return x; |
| 04 | return fib(x - 2) + fib(x - 1); |
| 05 | } |
| 06 | |
| 07 | static void Main(string[] args) |
| 08 | { |
| 09 | DateTime startTime = DateTime.Now; |
| 10 | DateTime endTime; |
| 11 | Console.WriteLine("Place 20: {0}", fib(20)); |
| 12 | endTime = DateTime.Now; |
| 13 | Console.WriteLine("Time: {0}", startTime - endTime); |
| 14 | Console.WriteLine("Place 30: {0}", fib(30)); |
| 15 | endTime = DateTime.Now; |
| 16 | Console.WriteLine("Time: {0}", startTime - endTime); |
| 17 | Console.WriteLine("Place 40: {0}", fib(40)); |
| 18 | endTime = DateTime.Now; |
| 19 | Console.WriteLine("Time: {0}", startTime - endTime); |
| 20 | |
| 21 | Console.ReadKey(); |
| 22 | } |
Note: I’m posting all the code on the off chance somebody reads my blog and would like bolster their self image by destroying my skills here. Look at the times though:
- Place 20: 6765
Time: 00:00:00
Place 30: 832040
Time: -00:00:00.0901296
Place 40: 102334155
Time: -00:00:09.8040976
I mean, come on, 9 seconds as compared to PHP’s 135 seconds!? I’m running 2 virtual machines on my host machine with only 2 gigs of ram, listening to a podcast, and c# runs under windows of all things. Reality is shattering before my eyes.
Anyways. The goal here is to implement the map in C#. Obviously C# will scoff at trying to use key=>value arrays. I’ve come across a few different way to do this, and it looks like a Hashtable is the simplest.
| C# | | copy code | | ? |
| 1 | static Hashtable map; |
| 2 | |
| 3 | static int fib(int x) |
| 4 | { |
| 5 | if (x < 2) return x; |
| 6 | if(!map.ContainsKey(x)) |
| 7 | map.Add(x, fib(x - 2) + fib(x - 1)); |
| 8 | return (int)map[x]; |
| 9 | } |
Our times?
- Place 20: 6765
Time: -00:00:00.0100144
Place 30: 832040
Time: -00:00:00.0100144
Place 40: 102334155
Time: -00:00:00.0100144
Not bad. There are some other ways to do this without the hashtable. You can use a ListCollection for example. But this seems like it works. Now to learn the more indepth aspects of hashtables in c#.

hey ryan, only stumbled on your site because we are ryan days and programmers but …
Did you know the v8 javascript engine [http://code.google.com/p/v8/] out performs c# quite a bit.
—-FIB—-
6765
20: 0.001
832040
30: 0.089
102334155
40: 4.942
—-FIB+memo—–
6765
20: 0
832040
30: 0
102334155
40: 0
the times are sub 1 ms which is pretty impressive.
for heavy crunching it would be worth it to write data to a file and process it with js. no other scripting language has an interpreter that will reduce the code to assembler.
Ahh yes, my arch nemesis in the fight for google placement! Are you referring to Rhino for the js compilation? I couldn’t comment on your site, so I’ll ask you my question here.
I have a Flex app that maintains login state through browser refresh using a SharedObject. If you close the browser though, the SharedObject persists while my login session with the backend doesn’t(phpsessid). So I use ExternalInterface to check for the current PHPSESSID cookie value, and compare it to the value I stored in the SharedObject, if they are different, I clear the sharedObject and force a relogin.
The problem is, this doesn’t work in Flex Builder because the Flex app is served from localhost, while the phpsessid cookie is set from the dev server serving the PHP code. Everything works fine when I load the Flex app from the dev server(same server, so access to cookies isn’t blocked).
Is that fixable without serving the PHP code from localhost as well?
=) hey yeah my site sucks right now sorry about the lack of a comment feature.
I just dump a bunch of code stuff in it with no particular order as whim dictates.
v8 is the javascript engine that powers chrome and is written in c++ as opposed to rhino which is a great attempt and a very standard js environment but slow as its in java. its just not designed for heavy lifting. It powers server js implementations like http://nodejs.org/
if your php server is using domain cookies ie:
“.domainname.com”
dot before the cookie will be set for all subdomains as well. you could just edit your systems hosts file and add an entry
local.myworkddomain.com 127.0.0.1
and test your flex from that address.
see http://us3.php.net/manual/en/function.session-set-cookie-params.php on how to change the default cookie domain in php
the domain value would be ‘.’.$_SERVER['SERVER_NAME'] in most cases
but you might not be able to change the php session cookie domain due to access or other political restrictions.
you could expose a webservice on the origin server to echo the phpsessid into a javascript response
url:
dev.workserver.com/sidservice.php?callback=sidcb
$sid);
$cb = isset($_GET['callback'])?$_GET['callback']:false;
if($cb) {
echo “$cb(“.json_encode($response).”);”;
} else {
echo json_encode($response);
}
?>
and then from js
var sidcb = function(data){
document.getElementsByTagName(‘object’)[0].loadsidcallbackfuntion(data.sid || ”);
}
(function(){
var scr = document.createElement(‘script’);
document.body.appendChild(scr);
scr.src = “dev.workserver.com/sidservice.php?callback=sidcb”;
})();
and in as
ExternalInterface.addCallback(‘loadsidcallbackfuntion’,function (sid: String) : void{
if(sid !== null && sid.length){
//success
} else {
//fail no sid
}
});
but i guess when it all comes down to it you have to add something to the dev environment in a place that can read the cookie data =) hope this helped nemesis.
–R
some of my php example got cut =/
$sid)…….
- one annoying thing about domain cookies is when you login in dev you will logout of production unless it specifies a more specifically targeted cookie
It did work, thanks for the advice! I checkout v8 also, hopefully I’ll have time today to play with it.