Skip navigation.

Posts tagged with "JAVASCRIPT"

The speed of the new generation of JavaScript engines

I just made a simple JavaScript performance test, and wanted to compare it to a similar implementation in C. Here is the code:

function testPerformance(a) {
  var len = a.length;
  var pos = 0;
  var start = new Date();
  var sum = 0;
  for (var i = 0; i < 500000000; i++) {
    sum += a[pos++];
    if (pos >= len)
      pos = 0;
  }
  var end = new Date();
  alert("Sum is: " + sum + ", took " + (end - start));
}
testPerformance([2, 3, 1, 4, 5, 1, 1, 3, 5, 1, 4, 6]);


I ran it on my 2.4GHz MacBook. In the new generation of JavaScript engines, the time it took was around 5 seconds, which means that you can do 100 million iterations per second. In C, with -O3, it was about 4 times faster. (two times faster without optimizations)

As a comparison, Opera 10 (which represents the older generation of JavaScript engines) is 20 times slower than the new generation of JavaScript engines.

Carakan, Opera's new generation JavaScript engine still under development, has two modes, one is with machine code generation, and one that only does byte code generation.

I will not tell you how fast Carakan is (that is something that will have to wait until a public version of Opera with Carakan is available), but I compared the two modes, and in this specific performance test, the version that generates machine code is a magnitude faster.

This is of course an extreme test, and does not reflect how JavaScript performs compared to C in general, or the difference between old and new generation of JavaScript engines.

According to my testing, Opera 10 runs this test faster than the equivalent code in Python.

Prototype-based inheritance

As you may already know, JavaScript uses prototype-based inheritance. In my opinion, JavaScript's implementation of prototype-based inheritance is not very good. Fortunately, JavaScript is a very flexible language, and I will here present a way to fix it.

I introduce two functions, $construct and $clone. $construct creates a new object with a defined prototype, and calls a function to initialize the new object. $clone creates a perfect clone of another object. To be able to do this, I add a value $proto to each object, pointing to the prototype object. (in some browsers, the extra property __proto__ exists, which provides even more flexibility than I show in this implementation)

The problem, as I see it, with JavaScript, is the hard connection between a function and a prototype.

I feel that I will not be able to explain what I mean right now, so let's just present the code, and hopefully you will understand anyway.

function $construct(protoobj, initfn, args) {
  var f = function() {};
  f.prototype = protoobj;
  var o = new f;
  o.$proto = protoobj;
  initfn.apply(o, args);
  return o;
}

function $clone(obj) {
  var f = function() {};
  f.prototype = obj.$proto;
  var o = new f;
  for (var x in obj) {
    if (obj.hasOwnProperty(x))
      o[x] = obj[x];
  }
  return o;
}

Do we really need classes in the JavaScript language?

Remember EcmaScript 4, the specification that does not exist. It will be replaced with EcmaScript 5 that is in the works. EcmaScript 5 is much closer to EcmaScript 3 than EcmaScript 4, that added a lot of things. One of the things added to EcmaScript 4 were classes. I thought that was one of the good additions compared to EcmaScript 3, but some of the other changes (like type declarations) I really disliked. So, after using some JavaScript toolkits, and even building my own class implementation, I think that classes as a language construct in JavaScript is not really needed.

As my class implementation Niclass shows, you only need to add 1.4 KB extra JavaScript code to get classes, which is only 0.5KB if you zip it over the wire. The implementation is fast, and does not add much memory overhead either. And I think it is easy enough to use, and the code looks good enough.

Niclass is still just a proof of concept, I haven't used it for any big project yet, not so strange since I wrote the code plus 3 blog posts about it today.

Niclass tutorial (my JavaScript class implementation)

The simplest thing is to create an empty class, that does not really include anything.

var A = $class();

var a = new A();
for (var x in a) {
  alert(x + ", value: " + a[x]);
}


We create a class with $class, and we list its members. The only member is $parent, with the value undefined.

Now, let's add a simple class that has a constructor that sets x to 3.

var A = $class({
  initialize: function() {
    this.x = 3;
  }
});

var a = new A();
alert(a.x);


Alerts 3 as expected.

We add a function, getX, to the class.

var A = $class({
  initialize: function() {
    this.x = 3;
  },
  getX: function() {
    return this.x;
  }
});

var a = new A();
alert(a.getX());


Still alerts 3.

We can let initialize take an argument, and send that argument to initialize through the new operation.

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  }
});

var a = new A(3);
alert(a.getX());


This code also alerts 3.

We can add a function setX to the class that takes an argument.

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  },
  setX: function(x) {
    this.x = x;
  }
});

var a = new A(3);
a.setX(5);
alert(a.getX());


Alerts 5, variation!

It is time to inherit. A new class B, inherits A. It implements getY and setY.

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  },
  setX: function(x) {
    this.x = x;
  }
});

var B = $class(A, {
  getY: function() {
    return this.y;
  },
  setY: function(y) {
    this.y = y;
  }
});

var b = new B(3);
alert(b.getX());


Alerts 3. The argument we supplied to the B constructor was sent to the initialize function in A. This happened because class B didn't have an initialize function. You can also see that B has inherited the function getX.

So, what happens if we add an initialize function in class B?

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  },
  setX: function(x) {
    this.x = x;
  }
});

var B = $class(A, {
  initialize: function(y) {
    this.y = y;
  },
  getY: function() {
    return this.y;
  },
  setY: function(y) {
    this.y = y;
  }
});

var b = new B(3);
alert(b.getX());
alert(b.getY());


First alerts undefined, then 3. So getX returns undefined, and getY returns 3. The initialize function in B was called, but not the one in class A.

We want to call the initialize function in class A, so we want to use $superinit.

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  },
  setX: function(x) {
    this.x = x;
  }
});

var B = $class(A, {
  initialize: function(x, y) {
    $superinit(this, x);
    this.y = y;
  },
  getY: function() {
    return this.y;
  },
  setY: function(y) {
    this.y = y;
  }
});

var b = new B(3, 4);
alert(b.getX());
alert(b.getY());


Alerts 3 and 4. Here we can see that the initialize function of class A was called with the help of $superinit. For $superinit to work, you need to supply this as the first argument, and the arguments that you want to send to the parent's initialize function as following arguments. Note that this is a little bit harder than in some other class implementations, but a verbosity that we can live with.

Time to try $super, which is basically the same as $superinit, but for all other functions.

var A = $class({
  initialize: function(x) {
    this.x = x;
  },
  getX: function() {
    return this.x;
  },
  setX: function(x) {
    this.x = x;
  }
});

var B = $class(A, {
  initialize: function(x, y) {
    $superinit(this, x);
    this.y = y;
  },
  getY: function() {
    return this.y;
  },
  setY: function(y) {
    this.y = y;
  },
  getX: function() {
    return $super(this, "getX") + 2;
  }
});

var b = new B(3, 4);
alert(b.getX());


Alerts 5. Class B implements getX by calling class A:s getX function with the help of the $super function, and adds 2 to that value. As in $superinit, the first argument is this. The second argument is "getX", you always need to declare the function that should be called in the super class. If the function that we call need its own arguments, we supply them after the first two arguments. This is also more verbose than in other class implementations, but I think it is good enough.

Time to introduce $extend. Extending a class that has already been created is a powerful concept, you can't do this in C++, but it is possible to do in Ruby. When you extend a class with a new function, you can use that function in already created functions of that class. (and of course, all of its sub classes)

function outputHello() {
  if (a.printHello)
    a.printHello();
  else
    alert("printHello function missing");
}

var A = $class();

var a = new A();

outputHello(a);

$extend(A, {
  printHello: function() {
    alert("Hello");
  }
});

outputHello(a);


Alerts "printHello function missing", then alerts "Hello". First time, printHello does not exist on the a object, and the second time, after the $extend function call, we can call a.printHello(), since the A class now includes the printHello function.

Classes in JavaScript

JavaScript is an prototype-based object-oriented language. This is much less common than class-based object-oriented languages. This makes JavaScript a little bit hard to learn for most experienced programmers. The good thing is that prototypes are more flexible than classes, and you can actually implement class-based object-orientation in a prototype-based language.

There are a number of JavaScript frameworks that among other things also implements class-based object-orientation. Two of these I have been looking closely at, Prototype and MooTools.

I like both of them, but in my opinion, MooTools class implementation looks a little better. However, MooTools class implementation has a lot of overhead per method call. Prototype is faster. But both are too complex in implementation for my taste.

So, with the experience of these two class implementations, I decided to try to come up with my own class implementation. This is what I wanted to accomplish:

  • A compact and easy to understand implementation
  • An implementation that has very little run-time overhead
  • Easy to use
  • Support extending a class after its creation, so you can add functions to already created objects of that class

As always, to accomplish what you want to, you have to compromise. The compromise I decided to do was to make it a little bit harder to call the parent's implementation of the same function, and also that the initialization code of a parent needs to be explicitly called.

There are still a few optimizations left to do, it will not add that many lines, but I decided to keep it a little bit simpler, 50 lines of code is enough for a blog post.

$class: the most important function. It creates and returns a new class. If the first argument is a function, that is treated like this will be the parent class. All remaining arguments are treated like they are objects, and all members (functions as well as other data) are copied to the class. If initialize is one of the members, it will be called when you call new on the new class. All arguments sent to new are sent to the initialize function.

$new is a special member in the class that will be used in the combination with new when the class is used as a parent class. $parent is there to be able to implement the $super and $superinit functions.

$super: call the parent's implementation of a function. self is the this object, and fname is the name of the method that should be called. The rest of the arguments are sent to the parent function.

$superinit: call the parent's initialize implementation. self is the this object. The rest of the arguments are sent to the parent function.

$extend: extend the class klass with new members. These members are available in all current and future objects created from this class. All the arguments except for the first are treated like objects, and all members in those objects are inserted in the class.

function $super(self, fname) {
  var args = [];
  for (var i = 2; i < arguments.length; i++)
    args[i - 2] = arguments[i];
  return $super.caller.$base.$parent.prototype[fname].apply(self, args);
}

function $superinit(self) {
  var args = [];
  for (var i = 1; i < arguments.length; i++)
    args[i - 1] = arguments[i];
  return $superinit.caller.$base.$parent.prototype["initialize"].apply(self, args);
}

function $extend(klass) {
  var dest = klass.prototype;
  for (var i = 1; i < arguments.length; i++) {
    var src = arguments[i];
    for (var x in src) {
      dest[x] = src[x];
      if (typeof dest[x] == "function")
        dest[x].$base = klass.prototype;
    }
  }
}

function $class() {
  var klass = function() { if (this.initialize) return this.initialize.apply(this, arguments); };
  var parent, start, proto_obj;
  if (typeof arguments[0] == "function")
    parent = arguments[0];
  if (parent) {
    proto_obj = new parent.$new;
    start = 1;
  } else {
    proto_obj = {};
    start = 0;
  }
  for (var i = start; i < arguments.length; i++) {
    var src = arguments[i];
    for (var x in src) {
      proto_obj[x] = src[x];
      if (typeof proto_obj[x] == "function")
        proto_obj[x].$base = proto_obj;
    }
  }
  proto_obj.$parent = parent;
  klass.prototype = proto_obj;
  klass.$new = function() {};
  klass.$new.prototype = proto_obj;
  return klass;
}


The code is not well tested yet, so there may be bugs. I will update this blog post when I find something that needs to be changed. I will also add an extra blog post with examples that uses the class library.

Update 1: Had to add $base to each function in a class, to be able to solve the problem with infinite recursion when trying to call the super function.
Update 2: In $superinit, the parameter needs to be called self, not obj.

JavaScript, Prototype and Ruby

, ,

A privilege I have working on a JavaScript engine is that I get to read a lot of Javascript code. I would like to write more JavaScript code than I currently do, the language is almost perfect for me. Ok, I would like a different syntax (I think that the C syntax family is wrong), but since I have been using C++ for more than ten years, I can live with that. In 2002 or 2003, I had to do some JavaScript related C++ coding, and I tried to understand prototypes (I didn't need to for my assigned task, but I did not really get it). For a long time, I was hoping for classes to be added to JavaScript, but now I am happy with it as it is. Please, no classes, and no static type checking.

I just started looking at the Prototype JavaScript Framework, and I found some things that I liked. First of all, the style of the code was pretty much how I want to code JavaScript. (2 spaces indentation, { on the same line as if/while, spaces in the right places, and the way functions are defined in an object. I would not code single line if/while bodies on the same line as the if/while statement, but I could probably adjust to that to.

One interesting aspect with Prototype is how it implements object orientation. If you read the document about class inheritance, you will see that it refers a lot to Ruby. I think Ruby developers have influenced Prototype a lot. It is basically Ruby inheritance in JavaScript.

This is a strength of prototype based languages. You can adjust the way it does object orientation, it is just more flexible than class based object orientation. But, flexibility usually makes it harder to learn, and you should probably add some kind of library on top of JavaScript. The way Prototype solves this has a rather clean syntax, and is as powerful as Ruby, which is enough for a lot of applications. (a nice thing in Ruby, JavaScript and Prototype is that you can add functions to already created objects of a certain type)

Javascript pattern: isolate init code

Last few weeks, I have been wading through lots of Javascript code, bugs have a tendency to force you to do things that you would normally not want to do. I have seen a lot of bad code, and some good. And, guess what, I still like Javascript a lot, in fact, I like it even more.

A common pattern found on pages on the Internet is using an anonymous function to encapsulate initialization code from polluting the global scope.

In Javascript, the scope of local variables is a function, not a block, as it is in many other popular languages. This is why you would like to use a function for encapsulation.

If you declare an anonymous function, and call it at the same time, it is approximately the same thing as an anonymous block in C++.

(function () {
  function printToScreen(str) {
    document.write("<p>" + str);
  }
  var s = "Hello world";
  printToScreen(s);
})();

// Here, s is not "Hello world", and printToScreen is not available.


You put the anonymous function inside parentheses, otherwise you will not be able to call it (because of Javascript's syntax). Then you call the function by adding (). In Javascript, you always have to add parentheses, since otherwise it is just a function reference, not a function call.

I always try to remember to add ; at the end of each statement. You do not have to do that always, ; is optional in a lot of places. The optional use of ; is one of the worst design mistakes in Javascript. The rules for when you are allowed to omit ; is too complex for most people to remember.

In my opinion, calling an anonymous function directly when it is declared has a quite ugly syntax. I think it is hard to read. If you want to spot if a file is using an anonymous function to encapsulate initialization code, look for the pattern "(function (" at the start of a line. If you match that pattern, it is almost certain that this is encapsulated initialization code. I think I would like to have some sort of support from my text editor for this kind of construct. (color coding or something similar)

Dragonfly and eval

,

I have to confess, I have not used Dragonfly that much. I am not a web developer, so that is not that strange, but Dragonfly is an Opera product, so I should be more familiar with it.

So, after my previous experiments with using eval to load libraries, I started wondering what happens if I try to debug the scripts that is loaded with eval.

This is the example code, I left out the HTML file.

// main.js

function load(name) {
  var s = new XMLHttpRequest();
  s.open("GET", name, false);
  s.send();
  eval(s.responseText);
}

onload = function() {
  load("loaded.js");
  f();
};


// loaded.js

f = function() {
  var a = 3;
  var b = 4;
  var c = a + b;
};


I was surprised to see that I was able to step through the eval code in Dragonfly. This is what I wanted. A problem was that, of course, the script loaded through eval did not have a name. A simple workaround is to add the name of the script at the top of the file. Another problem is that you can't select the eval script when the eval script is not running.

This is good enough to get my work done. I think it could be improved to increase its usefulness, I am sure the Dragonfly people at Opera has run in to this issue before, and I hope they are already working on improvements.

I am impressed with Dragonfly, it is really easy to use.

Libraries in Javascript

You can find a lot of great Javascript toolkits on the web, jQuery, Dojo, etc. This, however, is a mini-tutorial for how to build a system for working with libraries in Javascript.

Using libraries in Javascript is quite hard, since the language lacks both a way to load libraries, and clear namespaces.

Fortunately, Javascript, in combination with other modern web technologies, is very flexible. I have been looking at a number of different ways to use libraries in Javascript, and this is what I found to be easiest.

First, you need to have a framework for loading libraries. I call my framework library. It should be included in the html file, before the rest of your Javascript code. The framework initializes the object library in the global object, where you should put the libraries that you write, and also sets three functions on the global object, load that loads a Javascript library and runs the script, require that only loads a library if it hasn't already been loaded, and write, a function that writes a paragraph to the body of the html document, so that we can easily see what we are doing.

// library.js
library = {};

function load(name) {
  var s = new XMLHttpRequest();
  s.open("GET", name, false);
  s.send();
  eval(s.responseText);
}

function require(name) {
  if (!library[name])
    load(name + ".js");
}

function write(str) {
  var elm = document.createElement('p');
  elm.appendChild(document.createTextNode(str));
  document.getElementsByTagName("body")[0].appendChild(elm);
}


See that we are using XMLHttpRequest in synchronous mode to load Javascript files, and eval to parse and run the library. Make sure that there is not a lot of local variables that shadows global variables when you call require or load.

Then, we need to have an html file, it is an HTML 5 document, with an empty body.

<!DOCTYPE html>
<html>
<head>
<title>Testing library</title>
<script src="library.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</head>
<body></body>
</html>


Our main.js file needs a library to play with, hello.js. hello.js creates the object library.hello, and adds the function helloWorld to that object.

// hello.js
library.hello = {};

library.hello.helloWorld = function() {
  write("Hello World");
};


Then, in main.js, we add our main function as an onload handler, and use the hello library.

// main.js
onload = function() {
  require("hello");
  library.hello.helloWorld();
};


That's it. A library can also use require, since a library can depend on another library. You could also encapsulate things a little bit more, like putting load and require inside the library object, if you put a lot of things in the global object, it will be harder to use since other code might stop working. Using the name library for libraries might also be a bad idea.

Many toolkits use a tree or package structure for their libraries, I left that out.

Read this about JavaScript

Steve Yegge is a well known blogger. I would like to recommend that you read at least two things he has written. First, a very good one about how you can make dynamic languages run fast.

Then, one about what makes a dynamic language like JavaScript such a good idea.

I read and write a lot of JavaScript code these days. 4 years ago, I wrote about wanting to use JavaScript on the server. Now I want to use it for everything. Ok, you can make a better language than JavaScript, but JavaScript is standardized, and there are a lot of implementations out there. All implementations are treated equal, which is not true for Python or Ruby.

As a side-note, I am learning Lua. So much for just using JavaScript. :smile:

Yes we Carakan

We just announced that we are working on Carakan, a new fast JavaScript engine.

I am a proud member of that project, and we have fun while developing what I hope will be the best JavaScript engine out there.

Use JavaScript from inside Java

,

If you are using Java 6 (or 1.6, depending on how you count), the Rhino JavaScript engine is avaialable to you in the JDK. I didn't know this, and was very happy to see that it was. You can get a Java 6 package in Ubuntu.

If you want to run a javascript file, just use this code. Remember that things from client-side javascript, like the DOM, is not available.

// JavascriptLoader.java
// How to compile: javac JavascriptLoader.java
// How to run: java JavascriptLoader JS_FILENAME

import javax.script.*;
import java.io.*;

public class JavascriptLoader {
    public static void main(String args[])
    {
        if (args.length == 0) {
            System.out.println("Please provide a js file");
            return;
        }
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
        try {
            jsEngine.eval(new FileReader(args[0]));
        } catch (ScriptException ex) {
            System.out.println("ScriptException");
        } catch (FileNotFoundException ex) {
            System.out.println("FileNotFoundException");
        }
    }
}


Simple Javascript code you can use to test that things actually works:

for (var i = 0; i < 10; i++)
  println("Looping: " + i);

First development version of HTML+JS window framework

, ,

Since I finished the first milestone for my window framework during the first day of development, I will let you to see the code. I don't speak Javascript fluently, but some of you may learn some things from my code.

I use a simple pattern where I make data in the object private. You can also learn some things on how to use absolute positioning and DOM.

What this code implements right now is a view system. Each view has a size and a position, and a background color. A view can not have content. A view can have any number of child views. At the top there is a root view, that basically acts as a window. You should not place views belonging to the same parent on top of each other (even if I have done that in my example), since the order they are painted is undefined. (actually, the order is currently, first added, first painted)

This code is not rocket science. Of course more things will be added later, like content in the views, but this a good amount of code for people to learn how things work.

...and it works in both Opera and Firefox, KHTML untested (broken package in Ubuntu it seems), and IE also untested, I doubt that it works in IE.

CSS 3 to the rescue

, ,

Today I am trying to build a ui prototype with the help of HTML+JS. The first thing I noticed is that the security model in browsers is a barrier for creativity. Well, think again, ok, I have to only access local pages to be able to do things like getting the title or url from an iframe. I can live with that.

The second thing was that doing advanced stuff in CSS is maybe not that easy to keep compatibility even between Opera and Firefox. Well, only Opera is good enough for my purposes, anyone that need to see the ui prototype can download Opera.

The last thing was that doing a ui prototype without the possibility to shorten labels that do not fit will be very ugly. Fortunately, I found out that Opera since version 9 supports CSS 3 text-overflow: ellipsis in the form of -o-text-overflow.

Ooooh, and I have made some simple icons with Gimp, first time that I actually made something useful with that tool. The hardest thing was to select a color, took me a few minutes before I found the color selector, then even more to understand it.

Making a ui prototype with HTML+JS is not that hard. The problem is that the quick solution is not very easy to modify quickly, and that is not the way it should be when you want to prototype. So my next task is to build a prototyping framework, before I finish my ui prototype.

I have currently so much to do, it feels like I never will have the time to work again. :wink:

Helma, finally something for me!

Last few days I have been trying to learn Ruby on Rails. Even if it in some ways feel like a good thing, I am not really compatible with it. When something goes wrong, it goes very wrong, and it is really hard to debug. Also, the very idea behind Rails, generating a lot of code that you later can change is not my cup of tea.

Back to basics. Server-side Javascript is a topic that I have been eager to try out for a long time, last time Whitebeam seemed to be the coolest one, but I never got the time to start using it. And it is now 2 years since the page updated. The only framework listed on Wikipedia based on Javascript is Helma.

Helma seems still be to be active, with the latest release (1.6) only one month old. It is easy to install, except for the usual hard integration with a relational database, but I found out that if you can live with an XML database, you don't have to do any configuration.

The documentation is good (I probably should rate it very good, by open source standards), and the way it works seems also to be good. I may have encountered some bugs, but it also be just me not being a good enough tool user. I think the amount of test code on their site is rather limited.

Helma is written in Java and Javascript, these languages I know, so I can get a full understanding of the tool one day. (With Rails, I need to learn Ruby, a fun task, but it will take a while to become good at it)

So, I started looking at Helma this morning, and now I have finally made my first guestbook ever. A tool that I actually can use to produce my first web application is well worth some more time.
December 2009
M T W T F S S
November 2009January 2010
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31