Wednesday, September 03, 2008

My Test Drive of Google Chrome

When I told my wife that google has entered the browser arena with a new browser named "Google Chrome" her first Q was "so, is it in hebrew ?"

I told her that knowing google, it is either already in hebrew or will have hebrew in a short time.

well sure enough, after a quick install (no more then 2 min. I estimate) chrome was running  on my machine - In hebrew of course.


well - it looks different. has the googleish lightweight feel.

SEARCHBOX
first thing to I noticed was the search box - I started typing in it and got a bunch of suggestions for auto compleate - taken from my favorites, from what looks like google suggest and some other trivail domain compleations - not bad at all.

SPEED
second thing I noticed was that the site I asked for opened very quickly (probably has to do with a setting I later found they have for early dns resolution).

Dragable TABS
second thing I noticed was the tabs - well... being a developer with an itch for boundary scenarios I started adding new tabs, well other then the text being reduced to ...'s and then just to empty tabs (which still show the title as a tooltip) it handled my 30 or so tabs without any problem.
but hey I can't see the tab names so I tried to see if I could trag some of them to a "second row" of tabs - well my intuition was partly right - they did drag out but not to a second row but rather to a second window. dragging the tabs also works as you would expect between the new windows.

Processes
A quick look at the tasklist shows now 5 chrome.exe proccess - probably one that is somehow common + an additional procces for each tab that actually has content.

NO CRASHES - so far..

Blooger works
Well this blog post is being edited and posted via chrome.

For Developers

Google chrome has several nice features for developers

Javascript Console & Debugger
Google chrome comes with a built in javascript console and a javascript debugger which I will most definately have to take a look at.

a nice "View source" feature with color syntax

a cool internal task list
The internal task list (shift+Esc)  lets you see exactly each of your tabs 


an advanced "geek only" view shows also  is taking how much memory  resources (and also compare chromes memory usage to that of IE or FF)




What seems to be missing
Hey hmm.. pssst..  google people....
anybody knows how I can install my google toolbar on my google browser ????
(a quick search of the internet shows I am not the only one asking this ...).


as a web developer I can't no wander what trouble awaits for me trying to customize stuff to also look good also on chrome now. (think of all the web pages that have code that says "if its IE then else if its FF then else who cares.... - well here is another if for all of us).

well, here goes my first post via chrome - first test drive - no crashes at all.
 

Sunday, June 29, 2008

Two Tips For Debugging Flash Warnings

If you develop Flash widgets or application you might (and should) be familiar with the flash log.
One of the biggest issues with this log is that all the warnings and trace messages just pile up there regardless of what swf sent them.

Here are two simple tips to trace the "Warning: name is not a function" messages:

1. The reason you get those is because you are trying to call a function on some variable does not have such a function in its prototype chain.

2. To be able to identify what line in your code is causing those messages you can force the player to write out "Comments" into the log using the following syntax:

  ({}).THIS_IS_A_COMMENT_TO_THE_LOG()

This will trigget the same type of warning and so by placing several distinct such comments you can narrow the search and find the code line at fault.

Thursday, May 29, 2008

Gigya socialize live example

As you probably noticed (if you are reading this)
I have decided to add Gigya Socialize to my blog, (seemed only reasonable).

When you read a blog entry on my blog it will be reported to as an action you preformed and you can see both your friends actions and your own on the bottom of the right sidebar.

You can also read what was written about un in techrunch:
Gigya Socialize Goes Up Against Google Friend Connect.



Feel free to tell me what you think about this.

Monday, April 28, 2008

Optimizing Actionscript 2.0 - a bytecode perspective - Part I

Lately I have beeing looking at ways to optimize some actionscript 2.0 code.
I had two goals, the first was to reduce the size of the .swf file and the second was to make some parts of it faster at runtime.

I will try and write a series of posts describing what I have learned and still am learning from this.

Generally speaking - in most cases optimizing for speed comes at the expence of space and vice versa. also there are isues with how easy the code is to maintain after optimizing. With all that in mind I started looking at my code.

At first I was looking at the code at the action script level, but very soon i decided that If I realy want to understand what is gooing on under the hood I will have to look at bytecode (or actually P-Code at that stage).

Tools



The first thing that drew my attantion when I looked at the flasm output .flm file for my .swf was the repeating pattern

push 'com'
getVariable
push 'name'
getMember
push 'space'
getMember
push 'parts'
getMember
push 'functionName'
getMember


that was allover the place.
could it be?
each type that I write com.name.space.parts.function() it does all that ?
but wait - I have an import statement - is it not chaching those refrences somehow ?
argh... is that the price for deveoping a nice heirarchical class library ?

o.k. - lets cool down - lets try a simple example.

Lets look at the .flm of a project that includes two classes:


class com.epeleg.utils.Debug {
public static function traceThis(s) {
trace(s)
}
}


and a Main class:


import com.epeleg.utils.Debug;
class Main
{
public static function main():Void
{
Debug.traceThis('hello');
Debug.traceThis('world');
}
}


Lets build (in release mode) this and look at the results:
The .swf was 425 bytes.

if you realy must (and if you are like me - you probably do) see the entire .flm that was created Click Here:


otherwise (or afterwards) lets focus for a moment on the following:



push r:0, 'main'
function2 () (r:1='this')
push 'hello', 1, 'com'
getVariable
push 'epeleg'
getMember
push 'utils'
getMember
push 'Debug'
getMember
push 'traceThis'
callMethod
pop
push 'world', 1, 'com'
getVariable
push 'epeleg'
getMember
push 'utils'
getMember
push 'Debug'
getMember
push 'traceThis'
callMethod
pop
end // of function


this is the code that is generated by the compiler, yep - read it again...

now if I would go to optimize this by manipulating the code at this level I could probably do something like:


push r:0, 'main'
function2 () (r:1='this')
push 'world','hello', 1, 'com'
getVariable
push 'epeleg'
getMember
push 'utils'
getMember
push 'Debug'
getMember
dup
push 'traceThis'
callMethod
pop
push 'traceThis'
callMethod
pop
end // of function



well, this might work for some people, personally - (at least now) I had no intentions for manipulating the code at this level - what I wanted was a way to change my actionscript to force the compiler to create something smarter.

Attempt 2
change the main class to:
a Main class:


import com.epeleg.utils.Debug;
class Main
{
public static function main():Void
{
var TR=Debug.traceThis;
TR('hello');
TR('world');
}
}


and looking at the appripriate section again (sorry - no full code again) we now have:
push r:0, 'main'
function2 () (r:1='this')
push 'com'
getVariable
push 'epeleg'
getMember
push 'utils'
getMember
push 'Debug'
getMember
push 'traceThis'
getMember
setRegister r:2
pop
push 'hello', 1, r:2, UNDEF
callMethod
pop
push 'world', 1, r:2, UNDEF
callMethod
pop
end // of function

o.k. now this looks better, only thing is that the .swf is now 428 bytes.
this is reasonable beacuse we added the new variable to the constant pull.

also what is this UNDEF ?

lets try a different version for class main:

import com.epeleg.utils.Debug;
class Main
{
public static function main():Void
{
var DGB=Debug;
DGB.traceThis('hello');
DGB.traceThis('world');
}
}


swf size is still 428 bytes, but the ugly UNDEF is gone,


push r:0, 'main'
function2 () (r:1='this')
push 'com'
getVariable
push 'epeleg'
getMember
push 'utils'
getMember
push 'Debug'
getMember
setRegister r:2
pop
push 'hello', 1, r:2, 'traceThis'
callMethod
pop
push 'world', 1, r:2, 'traceThis'
callMethod
pop
end // of function


is This realy better - The Quick answer is No, actually the one with the UNDEF is better then the last one.
Why ? I will try and explain on the next Post where we wil take a closer look at the actual bytecode.

Thats all for now.

Monday, April 07, 2008

Configuring custom dynamic DNS (DDNS) agains ENOM on DD-WRT

I was messing around with my linksys trying to set up QoS and ended up resetting it,
loosing my DDNS settings and having to recreate them.
Took enough time for me to sit donw and write this down so that (my) next time would take less.

so here goes:
you would ususally have a single domain (e.g. dyn.yourdomain.com) that you would change dynamically and then have other domains that would map to it using CNAME entries.

If you have dynamic dns services provided by enom (I got mine when I moved to enom from registerfly) and you want your dd-wrt router to do the updating:

1) go to the web interface of your roter - ususally via 192.168.1.1
2) select the setup tab and the DDNS sub tab
3) in the DDNS Service combo choose Custom
4) DYNDNS Server should be set to dynamic.name-services.com
5) for some reason the UI does not allow you to leave out the User Name and Password so I just push _ in each of them
5)Hose Name should be set in our example to dyn.
6) URL should be set to /interface.asp?Command=SetDNSHost&Zone=yourdomain.com&DomainPassword=HEX_PASSWORD_YOU_GOT_FROM_ENOM&HostName=


[Update Aug 11th 2009: based on comment by Greg Bray]
6) URL should be set to /interface.asp?Command=SetDNSHost&Zone=yourdomain.com&DomainPassword=DOMAIN_ACCESS_PASSWORD_YOU_SET_UP&HostName=

To set up the DOMAIN_ACCESS_PASSWORD_YOU_SET_UP use the Domain Access Password field on the General Setting page of the Enom Control panel.

Greg was also kind enough to mention that:

Also, the URL that you listed will use the outgoing ip address as the value for updating the dns record. This should work in most cases, but if you want to specify the IP address for the record you need to include &Address=NEW_VALUE in the update url.
[/Update]

the hostname(5) itself will be appended to the DYNDNS Server(4) and URL(6) to create the entire URL for the request.

if you wish you can set the Additional DDNS Options field to --verbose 5 - this will show a much more informative output in the DDNS Status frame below after you press "Save Settings".

Done ?
now go to the Administration tab and select "Backup" to back up your configuration.

one last information bit:
Dynamic DNS updates FAQ on ENOM
http://www.enomcentral.com/help/faq_dynamicdns.asp

 
Clicky Web Analytics