<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>searching for signal</title>
	<atom:link href="http://blog.n01se.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.n01se.net</link>
	<description>theoretically unambiguous</description>
	<lastBuildDate>Wed, 14 Dec 2011 19:54:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Getting started with Clojure and Libvirt, Part 1</title>
		<link>http://blog.n01se.net/?p=452</link>
		<comments>http://blog.n01se.net/?p=452#comments</comments>
		<pubDate>Wed, 14 Dec 2011 19:51:21 +0000</pubDate>
		<dc:creator>kanaka</dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javadoc]]></category>
		<category><![CDATA[lein]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[repl]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=452</guid>
		<description><![CDATA[In this post I will give a gentle introduction to interacting with and controlling libvirt from Clojure. But first a couple of definitions: Libvirt is an API/toolkit for interacting with Linux virtualization systems (including KVM/QEMU, Xen, OpenVZ, Oracle VirtualBox, VMWare ESX/GSX/Workstation/Player, Microsoft Hyper-V, LXC, UML, etc). It is a very active project that is widely [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I will give a gentle introduction to interacting with and controlling libvirt from Clojure.</p>
<p>But first a couple of <strong>definitions</strong>:</p>
<ul>
<li><strong><a title="Libvirt" href="http://libvirt.org">Libvirt</a></strong> is an API/toolkit for interacting with Linux virtualization systems (including KVM/QEMU, Xen, OpenVZ, Oracle VirtualBox, VMWare ESX/GSX/Workstation/Player, Microsoft Hyper-V, LXC, UML, etc). It is a very <a title="Libvirt Changelog" href="http://libvirt.org/news.html">active project</a> that is widely used by many (maybe most) higher level virtualization platforms.</li>
<li><strong><a title="Clojure" href="http://clojure.org">Clojure</a></strong> is a relative new language that brings the dynamic power of LISP to the huge Java ecosystem. At <a title="LonoCloud" href="http://lonocloud.com">LonoCloud</a> we are using Clojure to create an operating system for cloud applications (more on that in later posts).</li>
</ul>
<p>It is a truism that any time you have two awesome (or not so awesome) ideas, eventually somebody will try to put them together. Fortunately in this case, Libvirt provides <a title="Libvirt Java API bindings" href="http://libvirt.org/sources/java/javadoc">Java API bindings</a> which means it also has Clojure bindings so combining them is quite easy. Let's get started...</p>
<h2>Prerequisites</h2>
<p>My assumption is that you have a access to Linux system on which you have administrator/sudo permission.</p>
<p>Familiarity with Clojure and libvirt will be helpful but not critical for following this walkthrough. If you are familiar with libvirt and the libvirt APIs but are new to Clojure then this walkthrough will give you a taste for the power and expressiveness of Clojure.</p>
<p>Install a Java JDK if you don't have one already. On an Ubuntu-like system you can do something like this:</p>
<pre class="brush: shell">sudo apt-get install openjdk-7-jdk  # 6 for older systems
sudo update-alternatives --config java  # select the one just installed</pre>
<p>Install the libvirt library and libvirtd service. On a Ubuntu-like system you can do something like this:</p>
<pre class="brush: shell">sudo apt-get install libvirt-bin libvirt0</pre>
<p>Download the leiningen script to somewhere on your PATH. Here is an example that assumes you have $HOME/bin on your PATH.</p>
<pre class="brush: shell">wget https://raw.github.com/technomancy/leiningen/stable/bin/lein -O $HOME/bin/lein
chmod +x $HOME/bin/lein</pre>
<h2>Launch the REPL</h2>
<p>Use lein to create a new project skeleton.</p>
<pre class="brush: shell">
lein new clj-libvirt
cd clj-libvirt
</pre>
<p>Add JNA and libvirt Java bindings to the leiningen project.clj file.  It should look something like this:</p>
<pre class="brush: clojure">
(defproject clj-libvirt "1.0.0-SNAPSHOT"
    :description "Use Libvirt from Clojure"
    :dependencies [[org.clojure/clojure "1.2.1"]
                    [net.java.dev.jna/jna "3.3.0"]
                    [org.libvirt/libvirt "0.4.7"]])
</pre>
<p>Use lein to pull down the project dependencies.</p>
<pre class="brush: shell">
lein deps
</pre>
<p>Start a Clojure REPL using lein. This REPL environment will have all the project dependencies available on the Java CLASSPATH.</p>
<pre class="brush: shell">
lein repl
</pre>
<h2>Libvirt from Clojure</h2>
<p>You should now have a Clojure REPL (read eval print loop) running with the "user=&gt;" prompt indicating that we are in the default REPL namespace called "user" and that the REPL is waiting for input. In the following examples I will show the REPL prompt followed by the text to type followed by the output and/or return value resulting from running the command.</p>
<p>Start by importing the Libvirt Connect object.</p>
<pre class="brush: clojure">
    user=&gt; (import '(org.libvirt Connect))
    org.libvirt.Connect
</pre>
<p>Now create a connection to the libvirt mock/test driver which is an ephemeral memory only driver for test purposes. The "Connect." syntax is the Clojure way of calling a Java constructor.</p>
<pre class="brush: clojure">
    user=&gt; (def mock-conn (Connect. "test:///default" false))
    #'user/mock-conn

    user=&gt; mock-conn
    #&lt;Connect org.libvirt.Connect@50903025&gt;
</pre>
<p>Make sure things are working by querying the Libvirt library version. Note that getLibVirVersion is a (Java) method of the connection object we defined above.</p>
<pre class="brush: clojure">
    user=&gt; (.getLibVirVersion mock-conn)
    7005
</pre>
<h2>Domains</h2>
<p>The test driver automatically starts with a faux virtual machine that is defined and "running". List the running domains (virtual machine instances are called domains in libvirt terminology).</p>
<pre class="brush: clojure">
    user=&gt; (.listDomains mock-conn)
    #&lt;int[] [I@4a504ec1&gt;
</pre>
<p>That's less than useful. This ugly output indicates that we have a Java array of ints. Wrap this in Clojure sequence which the REPL knows how to print.</p>
<pre class="brush: clojure">
    user=&gt; (seq (.listDomains mock-conn))
    (1)
</pre>
<p>Much better. This indicates we have one running domain that has an ID of 1. To interact with the domain you need use one of the Connect methods that returns a Domain object (domainLookupBy*). We know the running domain ID, so use domainLookupByID method to get a domain object. Then get the name of the domain and info about it.</p>
<pre class="brush: clojure">
    user=&gt; (def mock-dom (.domainLookupByID mock-conn 1))
    #`user/mock-dom

    user=&gt; mock-dom
    #&lt;Domain org.libvirt.Domain@5a56b93a&gt;

    user=&gt; (.getName mock-dom)
    "test"

    user=&gt; (.getInfo mock-dom)
    #&lt;DomainInfo state:VIR_DOMAIN_RUNNING
    maxMem:8388608
    memory:2097152
    nrVirtCpu:2
    cpuTime:1322765442068879000
    &gt;
</pre>
<h2>Domain Control</h2>
<p>Now stop the domain and verify that it is off.</p>
<pre class="brush: clojure">
    user=&gt; (.destroy mock-dom)
    nil

    user=&gt; (.getInfo mock-dom)
    #&lt;DomainInfo state:VIR_DOMAIN_SHUTOFF
    maxMem:8388608
    memory:2097152
    nrVirtCpu:2
    cpuTime:1323714453027037000
    &gt;
</pre>
<p>Now start it back up again.</p>
<pre class="brush: clojure">
    user=&gt; (.create mock-dom)
    0

    user=&gt; (.getInfo mock-dom)
    #&lt;DomainInfo state:VIR_DOMAIN_RUNNING
    maxMem:8388608
    memory:2097152
    nrVirtCpu:2
    cpuTime:1323714627116985000
    &gt;
</pre>
<h2>Getting More Info</h2>
<p>The Connection and Domain objects have a number of useful methods.  List their methods names by mapping the getName method onto the list of methods.</p>
<pre class="brush: clojure">
    user=&gt; (map #(.getName %) (.getMethods (class mock-conn)))
    ("finalize" "close" "getType" "getHostName" ...)
    user=&gt; (map #(.getName %) (.getMethods (class mock-dom)))
    ("shutdown" "finalize" "getName" "destroy" ...)
</pre>
<p>Those are mind-numblingly long lists of methods. For a user-readable reference you will probably want to use the <a title="Libvirt javadocs" href="http://libvirt.org/sources/java/javadoc/org/libvirt/package-summary.html">Libvirt javadoc page</a>.</p>
<h2>Conclusion</h2>
<p>That's all for now. I hope you have seen in this post how easy it is to interact with and control Libvirt from Clojure. Of course, we haven't actually done anything useful yet since the only interaction was with Libvirt mock/test driver. In a follow-up post I will walk through creating and interacting with <i>real</i> virtual domains instead of just <i>virtual</i> virtual domains.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=452</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Most Important Parts of HTML5</title>
		<link>http://blog.n01se.net/?p=375</link>
		<comments>http://blog.n01se.net/?p=375#comments</comments>
		<pubDate>Sat, 06 Aug 2011 15:57:08 +0000</pubDate>
		<dc:creator>kanaka</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[ramble]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[native applications]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web applications]]></category>
		<category><![CDATA[web apps]]></category>
		<category><![CDATA[Web Audio]]></category>
		<category><![CDATA[Web Workers]]></category>
		<category><![CDATA[webgl]]></category>
		<category><![CDATA[websocket]]></category>
		<category><![CDATA[websockets]]></category>
		<category><![CDATA[whatwg]]></category>
		<category><![CDATA[WOFF]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=375</guid>
		<description><![CDATA[or Why &#60;video&#62; and &#60;audio&#62; are Boring or The New Web Platform or An Introduction to HTML5 &#160; A Little Perspective The Birth of the Web 20 years ago today (Aug 6th, 1991), Tim Berners-Lee released the World Wide Web on the world while working at CERN. Actually what he released was a program called [...]]]></description>
			<content:encoded><![CDATA[<h2 style="text-align: center">or <em><strong>Why &lt;video&gt; and &lt;audio&gt; are Boring</strong></em></h2>
<h2 style="text-align: center">or <em><strong>The New Web Platform</strong></em></h2>
<h2 style="text-align: center">or <em><strong>An Introduction to HTML5</strong></em></h2>
<p>&nbsp;</p>
<h2>A Little Perspective</h2>
<h4>The Birth of the Web</h4>
<p>20 years ago today (Aug 6th, 1991), Tim Berners-Lee <a title="Email from Berners-Lee on Aug 6th, 1981" href="http://www.w3.org/People/Berners-Lee/1991/08/art-6484.txt">released</a> the World Wide Web on the world while working at <a title="European Organization for Nuclear Research" href="http://www.cern.ch">CERN</a>.  Actually what he released was a program called "WorldWideWeb" which was eventually renamed "Nexus" to clarify the distinction between the concept of the World Wide Web and the browser itself.<span id="more-375"></span></p>
<p>The initial browser could render documents written in HyperText Markup Language (HTML). The first HTML supported some limited formatting and hyperlinks (we just call them links now) to other documents.  Here is a screenshot from 2 years later when color and inline images were added:</p>
<div class="wp-caption aligncenter" style="width: 410px"><img class="  " src="http://www.w3.org/History/1994/WWW/Journals/CACM/screensnap2_24c.gif" alt="WorldWideWeb browser running on a NeXT System" width="400" height="297" /><p class="wp-caption-text">WorldWideWeb Browser Running on a NeXT System</p></div>
<h4>﻿﻿The Rise of the Web</h4>
<p>In the next 10 years "the Web" exploded in terms of innovation, standardization (<a href="#footnote1">Footnote 1</a>), number of users, browsers (installs and variations), web servers (installs and variations), and economic impact. With the release of Mosaic (at <a title="The National Center for Supercomputing Applications at the University of Illinois" href="http://www.ncsa.illinois.edu/">NCSA</a>) in 1993, with its seamless integration of graphics and text, the World Wide Web quickly grew to become the dominant use of the Internet and the driving force behind Internet adoption. In fact, for most computer users "the Web" and "the Internet" have become synonymous.</p>
<h4>The Fall of the Web</h4>
<p>At the turn of the century, Web innovation slowed due to the emergence of Microsoft's Internet Explorer as a near monopoly in the web browser market.  Once Microsoft achieved a controlling share of the web browser market they lost interest in driving or cooperating on new Web standards and technologies because this might threaten their profitable Windows platform.</p>
<h4>The Rise of the Web (Again)</h4>
<p>In the last three years there has been a new explosion of Web innovation.  The Web has been released from its cage by three main trends: the rise of Mozilla Firefox (a spiritual descendant of the Mosaic browser), the rise of Google Chrome, and the rise of mobile devices.</p>
<div class="wp-caption aligncenter" style="width: 410px"><img class=" " src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Usage_share_of_web_browsers_%28Source_StatCounter%29.svg/1000px-Usage_share_of_web_browsers_%28Source_StatCounter%29.svg.png" alt="Web Browser Market Share 2008-2011 (Wikimedia)" width="400" height="400" /><p class="wp-caption-text">Web Browser Market Share (Wikimedia)</p></div>
<p>&nbsp;</p>
<p>A core part of human nature is to <a title="Genesis 2:19-20" href="http://www.biblegateway.com/passage/?search=Genesis+2%3A19-20&amp;version=NIV">give names to everything</a> including to abstract concepts. The new energy and innovation surrounding the Web platform is no exception; it needs a name. Which brings us to "HTML5" ...</p>
<p>&nbsp;</p>
<h3>"HTML5"</h3>
<p>Technically, HTML5 is a <a title="W3C HTML5 Specification" href="http://www.w3.org/TR/html5/">specification</a> from the World Wide Web Consortium (W3C)  (<a href="#footnote2">Footnote 2</a>). Many pedants will claim this is the only correct usage. For the rest of us, HTML5 is a useful term to describe the rapid changes that are currently happening to the Web platform. This is what I will mean when I use the term "HTML5". I will refer to the formal specification as "W3C HTML5".</p>
<h3>W3C HTML5</h3>
<p>Although the W3C HTML5 specification is not going to be officially complete until 2014, <a title="W3C HTML5 End of Last Call" href="http://blog.whatwg.org/weekly-end-of-last-call">the specification finished last call review</a> earlier this week (Aug 3rd) so there are unlikely to be any radical changes in the next three years before finalization.</p>
<h4>W3C HTML5 is Boring</h4>
<p>The W3C HTML5 is very important at one level, but it is also pretty boring. It is basically a formal description of the state-of-the art in the Web platform from 3 years ago. The actual content of the specification is pretty mundane (even apart from the dry and technical nature of specification documents). The most interesting API in the W3C HTML5 is the Canvas 2D Context and that is defined in a <a title="W3C Canvas 2D Context Specification" href="http://dev.w3.org/html5/2dcontext/">separate document</a>.</p>
<h4>W3C HTML5 is Important</h4>
<p>However, the W3C HTML5 is important because it makes official all the good ideas that have been learned over the years and it attempts to remove most of the things that are now considered mistakes. It also brings a great deal of consistency and completeness to the various DOM APIs and HTML elements. And probably most importantly, it has brought the various browser makers into agreement. This means web developers that develop against what is defined in the W3C HTML5 specification should have one application that works well on all recent browsers versions without the need for browser specific kludges.</p>
<h3>W3C HTML5 vs HTML5</h3>
<p>If I were to sum up the differences between the W3C HTML5 specification and the larger concept of HTML5 it would be this:</p>
<ul>
<li>The W3C HTML5 promotes many of the existing second class elements of the Web such as video, audio, animations, smart forms, etc into first class elements.</li>
<li>HTML5 (the common usage) takes those new elements and adds power and functionality to them that was not previously possible. HTML5 also creates a whole new set of first class elements out of technologies that were not part of the Web in the first place such as hardware device access, binary data, file system access, multiprocessing, etc.</li>
</ul>
<p>Or another way of summing up the relationship between the two:</p>
<p style="padding-left: 30px">The W3C HTML5 specification serves as the foundation and framework upon which all the interesting HTML5 developments are happening.</p>
<p>&nbsp;</p>
<h2>The Most Important Parts of HTML5</h2>
<p>Now we come to my purpose for this article: to list and describe the HTML5 APIs, standards, and technologies that are most important (and most interesting). I have tried to imagine the Web as it will exist five years from now and from that vantage point determine what parts of HTML5 were most crucial in bringing us to that imagined future.</p>
<p>The following list is ordered from most to least important. Obviously this is just my opinion. I do web application development (<a title="noVNC - HTML5 VNC Client" href="https://github.com/kanaka/noVNC">noVNC</a>, <a title="websockify - WebSocket to TCP socket proxy/bridge" href="https://github.com/kanaka/websockify">websockify</a>) and participate in HTML5 working groups and discussions, but the future is always more interesting (and less) than any experts can predict.</p>
<p>So without further ado...</p>
<p>&nbsp;</p>
<h3>1. Faster Javascript Engines</h3>
<p><strong> </strong> The Web as a application platform is built on this more than anything else. The new Javascript engines are the warp drive for the Web. Without the warp drive, Star Trek is a story that takes place on earth (or at best in one solar system). Without the massive increase in Javascript performance we would still be talking about web pages and not web applications.</p>
<h3>2. WebSockets</h3>
<p><strong> </strong>This moves the browser solidly into the space of highly interactive networked applications. After fast Javascript engines, low-latency networking has the largest potential for allowing the Web to conquer new application domains.</p>
<h3>3. Binary Data Types (Typed Arrays and Blobs)</h3>
<p>Javascript started its life as a way to do validation of textual form data.  However, many of the first class elements introduced in HTML5 contain, receive and/or output binary data and so native binary data types in Javascript has become a necessity. Developers have used various hacks to encode binary data in old Javascript data types for many years. But using these hacks is a significant barrier and the full power of HTML5 will not be unleashed without native binary data support.</p>
<h3>4. Web Audio API</h3>
<p><strong> </strong> This is not the &lt;audio&gt; tag but rather the APIs/proposals for allowing low-latency, direct audio manipulation from Javascript.  The &lt;audio&gt; tag (which is part of W3C HTML5) allows an audio file to be embedded directly in a web page and it provides a playback and synchronization API.</p>
<p>The Web Audio API proposals allows for direct creation and manipulation of audio waveforms and also address issues of high-latency playback that exist in current &lt;audio&gt; tag implementations. These proposals are still very young and the final solutions may merge with the &lt;audio&gt; tag, but the issues addressed by the Web Audio API proposals will be in future browsers in one form or another.</p>
<h3>5. Canvas 2D Context</h3>
<p><strong> </strong>Direct pixel manipulation. Everybody agrees it is important so there is not much I will add. I put it below the Web Audio API because much of what can be done with Canvas 2D Content can be done with other methods (SVG, WebGL, CSS3).</p>
<h3>6. CSS3 and WOFF</h3>
<p><strong> </strong>Cascading Style Sheets 3 and the Web Open Font Format together bring the full power of design, typography, layout, and visual transformation to the web. Also, with CSS3 (in particular the Flexible Box Model), web applications will finally have a simple and powerful way of doing user interface layout without the element positioning mess that is necessary with CSS2.</p>
<h3>7. Local Storage, Offline Applications and the File APIs</h3>
<p><strong> </strong> There are many application domains that are just not feasible without fast, local and persistent storage (at least not until everyone has cheap Gigabit Internet connections). Some form of local storage is also necessary for web applications to be usable when there is no Internet connection available. There are a number of APIs/standards being developed in this area but they are all addressing different aspects of the same fundamental limitation of pre-HTML5 browsers.</p>
<h3>8. Web Workers</h3>
<p><strong> </strong>Moore's Law is dead, long live Moore's Law! The year-after-year exponential increase in CPU frequency due to Moore's Law ended several years ago. But Moore's Law  was actually a statement about transistor cost/density and this has not changed, it simply has a new face: processor cores per square inch of chip. In a few years, even your mobile phone will have more processor cores than you have fingers.</p>
<p>New software models are required to take full advantage of the new multi-core reality of Moore's Law. Fortunately, even though Javascript has always been a single threaded language it was also designed from the beginning to an event driven language. This means that while multiple lines of Javascript in the same web application cannot be running simultaneously, the browser can be doing multiple things at once on behalf of that Javascript code that is running.</p>
<p>Being event driven only goes so far. The Web Workers specification was created to allow a single web application to have multiple threads of Javascript running simultaneously. To avoid the massive complexity that usually comes with multi-threaded programming (locks, special data structures, etc), Web Workers are independent Javascript contexts and they can only interact with each other and with the main Javascript thread using event driven message passing.</p>
<h3>9. SVG 1.1/2.0</h3>
<p><strong> </strong> The SVG (Scalable Vector Graphics) format has been around for a long time and some browsers have been able to embed SVG images into web pages. SVG is finally starting to be adopted by all browser makers in a form that adds powerful APIs and that allows full access and manipulation to the contained elements (i.e. a truly first class element).</p>
<p>SVG is actually a difficult one to place in the list. Many (perhaps even most) of the uses of the Canvas 2D Context are actually more appropriate to SVG and in many ways SVG is far more powerful. However, SVG has had an uneven history and I fear that it has accumulated some unjustified mental baggage that will prevent it from being as fundamental and important as it otherwise would be. I will be happy to be proved wrong if it turns out to be more important than I have rated it.</p>
<h3>10. WebGL</h3>
<p><strong> </strong> This is the Canvas 3D Context and it is basically a hardware accelerated OpenGL API for the Web. Like SVG, this is potentially a very important piece of HTML5. But I say potentially because Microsoft has been somewhat dismissive of WebGL (possibly since it is defined in terms of OpenGL rather than their own DirectX API) and so there is uncertainty about whether this will ever make it into Internet Explorer. If there were less uncertainty I would place this higher in the list because it brings the Web to the doorstep of so many new application domains (including 3D games).</p>
<h3>11. All the Rest</h3>
<p><strong> </strong>The ultimate vision of many who are pushing forward the Web platform is to make the Web platform as powerful, capable and comprehensive as native applications.  The first 10 items each open up the Web platform to large new application domains that have historically only been possible with native applications. But they leave many gaps that must be filled before we reach a future where the question asked by developers is no longer "<em><strong>Can I build this as a web application?</strong></em>" but rather "<em><strong>Do I want to build this as a web application?</strong></em>"</p>
<p>There are numerous proposals that are being worked on to address the gaps in web application functionality. Several of them would probably be higher on the list if they were further along or had less uncertainty about whether they will be universally adopted by all browser makers. Here are just a few of the proposals/APIs that are attempting to fill the gaps:</p>
<ul>
<li><strong>WebRTC/Stream API</strong>: Peer-to-peer video conferencing.</li>
<li>﻿<strong>Geolocation</strong>: Where in the World am I?</li>
<li><strong>Orientation</strong>: Which way is up?</li>
<li><strong>Crypto</strong>: Encrypt/decrypt efficiently in Javascript</li>
<li><strong>WebCL</strong>: The Web version of OpenCL. Who wouldn't want to use the GPU directly for computation from Javascript?</li>
<li><strong>WebNotifications</strong>: Tell me what's happening, but gently.</li>
<li><strong>Web Intents</strong>: Associate data types with default actions and pass data back and forth between web applications. Your favorite web application for editing images will inevitably be different then the default one for that web based slideshow application. Shout with me: "OLE!"</li>
<li><strong>Page Visibility</strong>: Imagine how much energy the world would be save if those animations and movies stopped rendering when you aren't looking at them.</li>
<li><strong>requestAnimationFrame</strong>: with setTimeout you get 100 FPS or you get 2 FPS (often within the same second). Now you can get a consistent 30 FPS. And there was much rejoicing.</li>
<li><strong>Microdata</strong>: unambiguous parsing of embedded machine-readable data.</li>
<li><strong>Etc</strong></li>
<li><strong>Etc</strong> (<a href="#footnote3">Footnote 3</a>)</li>
</ul>
<p>&nbsp;</p>
<div class="wp-caption aligncenter" style="width: 210px"><img src="http://imgs.xkcd.com/comics/mac_pc.png" alt="Mac vs PC vs Browser (xkcd.com)" width="200" height="371" /><p class="wp-caption-text">Mac vs PC vs Browser (from xkcd.com)</p></div>
<h3>What about &lt;video&gt; and &lt;audio&gt;?</h3>
<p>The &lt;video&gt; and &lt;audio&gt; tags are probably the HTML5 features that have caused the most excitement (and angst) on the web regarding HTML5. In fact, some of you may have scanned ahead looking for them in the list and were surprised they were not #1 and #2. These two elements are part of W3C HTML5 and while they do make first class elements out of what has traditionally been second class (e.g. done with Flash), they are still really just a better way of doing what has already been done. The &lt;video&gt; and &lt;audio&gt; tags don't significantly expand the scope of what web applications are capable of so that is one reason why they are not on the list. Another problem with these tags is that the list of supported media formats is inconsistent across browsers. Until this is resolved, their adoption will be hampered. (<a href="#footnote4">Footnote 4</a>)</p>
<hr />
<p>&nbsp;</p>
<h2>Footnotes</h2>
<p>These were originally inline in the article and they seemed to interrupt the flow so I moved them here. And even without these notes the article is still too long.</p>
<h4><a name="footnote1">Footnote 1</a></h4>
<p>Here are some notable standards that developed around the Web platform in the first few years after the first web browser was released by Tim Berners-Lee:</p>
<ul>
<li>1995 - <a title="IETF HTML 2.0 Specification" href="http://tools.ietf.org/html/rfc1866">HTML 2.0</a> is published as the first official HTML standard.</li>
<li>1995 - HTML make the first baby step toward becoming dynamic and interactive when JavaScript is created by Brendan Eich and added to Netscape Navigator 2.</li>
<li>1996 - The CSS1 (Cascading Style Sheets) specification is completed and parts of it appear in Internet Explorer 3. Part of the reason for CSS is to separate web page appearance from content and functionality. This follows as well established principle in computer science of separating concerns.</li>
<li>1998 - The DOM Level 1 (Document Object Model) specification, the API of HTML elements on a page, is published by the W3C.</li>
</ul>
<h4><a name="footnote2">Footnote 2</a></h4>
<p>I should note another important group (with a long and forgettable name) that is involved in HTML standards is the <a title="WHATWG" href="http://www.whatwg.org">Web Hypertext Application Technology Working Group (WHATWG)</a>. Many (perhaps most) of the people at WHATWG also participate in work at the W3C. The WHATWG can be thought as a more dynamic and less restricted version of the W3C.</p>
<p>The WHATWG maintains two overarching standards documents. The first is <a title="WHATWG HTML Specification" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">HTML</a>.  Many of the ideas that are in the W3C HTML5 were first documented here. This document can be thought of HTML5+. The second standard document is called <a title="WHATWG Web Apps 1.0 Specification" href="http://www.whatwg.org/specs/web-apps/current-work/complete/">Web Apps 1.0</a>.  This contains the content of the HTML document and adds many of the APIs that are considered important for the Web to become a full fledged application platform.</p>
<p>The WHATWG Web Apps 1.0 document is much closer to what people generally mean when they use the term "HTML5", however, even that does not encapsulate the whole meaning. There are many other APIs and proposals that are part of the new energy of the Web that are or will make their way into most browsers (either via the standards process or not).</p>
<h4><a name="footnote3">Footnote 3</a></h4>
<p>Etc. I am not aware of a web proposal/API yet with those three letters. The question is will this article will make it more or less likely that there will be one soon?</p>
<h4><a name="footnote4">Footnote 4</a></h4>
<p>By combining fast Javascript, WebSockets, Canvas, Web Audio, and binary data types you can have video and audio without the &lt;video&gt;/&lt;audio&gt; tags and without any plugins. The frame rate and resolution might be lower than desired but it is possible.</p>
<hr />
<p>&nbsp;</p>
<h2>Resources</h2>
<p>&nbsp;</p>
<ul>
<li><a title="Dive Into HTML5" href="http://diveintohtml5.org/">Dive Into HTML5</a></li>
<li><a title="HTML5Rocks" href="http://www.html5rocks.com/en/">HTML5Rocks</a></li>
<li>Excellent <a title="HTML5Rocks Presentation" href="http://slides.html5rocks.com/#landing-slide">Presentation on HTML5</a> from HTML5Rocks</li>
<li><a title="When can I use..." href="http://caniuse.com/">When can I use... </a> Compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.</li>
<li><a title="HTML5 Readiness" href="http://html5readiness.com/">HTML5 Readiness</a> - Flower chart of HTML5 &amp; CSS3 features in major browser versions</li>
<li><a title="The HTML5 Test" href="http://beta.html5test.com/">The HTML5 Test</a> - How well does your browser support HTML5?</li>
<li><a title="HTML5 Browser API list" href="http://platform.html5.org/">The Web Platform: Browser technologies</a> ()</li>
<li><a title="HTML5 Twitter Page" href="http://twitter.com/#!/html5">HTML5 Tweets</a></li>
<li><a title="W3C blog" href="http://www.w3.org/QA">W3C Blog</a></li>
<li><a title="WHATWG blog" href="http://blog.whatwg.org">WHATWG Blog</a></li>
<li><a title="Google Chrome blog" href="http://chrome.blogspot.com">Google Chrome Blog</a></li>
<li><a title="Mozilla Firefox blog" href="http://blog.mozilla.com/blog/category/firefox/">Mozilla Firefox Blog</a></li>
<li><a title="Opera Developer blog" href="http://my.opera.com/ODIN/blog/">Opera Developer Blog</a></li>
<li><a title="Microsoft IE blog" href="http://blogs.msdn.com/b/ie/">Microsoft Internet Explorer Blog</a></li>
<li><a title="&quot;An Open Web&quot; online book" href="http://en.flossmanuals.net/an-open-web/">"An Open Web" book</a></li>
<li><a title="20 Things Google comic" href="http://www.20thingsilearned.com/en-US">"20 Things I Learned About Browsers and The Web"</a> Google comic</li>
<li><a title="What is HTML5 (oreilly.com)" href="http://radar.oreilly.com/2011/07/what-is-html5.html">"What is HTML5"</a></li>
</ul>
<h2>Links</h2>
<p>&nbsp;</p>
<ul>
<li><a title="Early Web History (W3C)" href="http://www.w3.org/History.html)">Early History of the Web</a> (W3C)</li>
<li><a title="Where the web was born (CERN)" href="http://public.web.cern.ch/public/en/about/web-en.html)">Where the web was born</a> (CERN)</li>
<li><a title="W3C" href="http://www.w3.org/">W3C</a></li>
<li><a title="W3C HTML5" href="http://www.w3.org/TR/html5/">W3C HTML5</a></li>
<li><a title="WHATWG" href="http://www.whatwg.org/">WHATWG</a></li>
<li><a title="WHATWG HTML Specification" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">WHATWG HTML</a></li>
<li><a title="WHATWG Web Apps 1.0 Specification" href="http://www.whatwg.org/specs/web-apps/current-work/complete/">WHATWG Web Apps 1.0</a></li>
<li>1. EcmaScript/Javascript: <a title="ECMA-262 Standard" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262</a></li>
<li>2. WebSockets
<ul>
<li>API: <a title="W3C WebSockets API" href="http://dev.w3.org/html5/websockets/">W3C</a>, <a title="W3C WebSockets API" href="http://www.whatwg.org/specs/web-apps/current-work/complete/network.html">WHATWG</a></li>
<li>Protocol: <a title="IETF/HyBi WebSockets Protocol" href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10">IETF/HyBi</a></li>
</ul>
</li>
<li>3. Binary Data Types
<ul>
<li><a title="Typed Array Specification" href="http://www.khronos.org/registry/typedarray/specs/latest/">Typed Arrays</a></li>
<li><a title="Blob Type Specification" href="http://www.w3.org/TR/FileAPI/#blob">Blob Type</a></li>
</ul>
</li>
<li>4. Web Audio: <a title="Google Web Audio API" href="http://chromium.googlecode.com/svn/trunk/samples/audio/specification/specification.html">Google</a>, <a title="Mozilla Audio Data API" href="https://wiki.mozilla.org/Audio_Data_API">Mozilla</a>, <a title="W3C Audio" href="http://www.w3.org/2011/audio/">W3C</a></li>
<li>5. Canvas 2D Context: <a title="W3C Canvas 2D Context Specification" href="http://www.w3.org/TR/2dcontext/">W3C</a>, <a title="WHATWG Canvas Specification" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">WHATWG</a></li>
<li>6. CSS and WOFF
<ul>
<li>CSS3: <a title="W3C CSS" href="http://www.w3.org/Style/CSS/current-work">W3C</a></li>
<li>WOFF: <a title="W3C WOFF Specification" href="http://www.w3.org/TR/WOFF/">W3C</a></li>
</ul>
</li>
<li>7. Local Storage, Offline Application and the File APIs
<ul>
<li>Web Storage: <a title="W3C Web Storage Specification" href="http://dev.w3.org/html5/webstorage/">W3C</a></li>
<li>IndexedDB: <a title="W3C IndexedDB Specification" href="http://www.w3.org/TR/IndexedDB/">W3C</a></li>
<li>Offline Applications: <a title="W3C Offline Applications Specification" href="http://dev.w3.org/html5/spec/offline.html">W3C</a>, <a title="WHATWG Offline Applications Specification" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html">WHATWG</a></li>
<li>File/Reader: <a title="W3C File (Reader) API Specification" href="http://dev.w3.org/2006/webapi/FileAPI/">W3C</a></li>
<li>File Writer: <a title="W3C File Writer API Specification" href="http://dev.w3.org/2009/dap/file-system/file-writer.html">W3C</a></li>
<li>File Dir/System: <a title="W3C File Directories/System API Specification" href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html">W3C</a></li>
</ul>
</li>
<li>8. Web Workers: <a title="W3C Web Workers Specification" href="http://dev.w3.org/html5/workers/">W3C</a>, <a title="WHATWG Web Workers Specification" href="http://www.whatwg.org/specs/web-apps/current-work/complete/workers.html">WHATWG</a></li>
<li>9. SVG 1.1/2.0:
<ul>
<li><a title="W3C SVG 1.1 Specification" href="http://www.w3.org/TR/SVG/">W3C 1.1</a></li>
<li><a title="W3C SVG 2.0 Roadmap" href="http://www.w3.org/Graphics/SVG/WG/wiki/Roadmap">SVG 2.0 W3C Roadmap</a></li>
</ul>
</li>
<li>10. <a title="Khronos WebGL 1.0 Specification" href="https://www.khronos.org/registry/webgl/specs/1.0/">WebGL</a></li>
<li>11. All the Rest
<ul>
<li><a title="Google WebRTC Project" href="https://sites.google.com/site/webrtc/">WebRTC</a>/Stream API</li>
<li><a title="W3C Geolocation Specification" href="http://dev.w3.org/geo/api/spec-source-v2">Geolocation</a></li>
<li><a title="W3C Orientation Specification" href="http://dev.w3.org/geo/api/spec-source-orientation">Orientation</a></li>
<li><a title="Mozilla DomCrypto API Proposal" href="https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest">Crypto</a></li>
<li><a title="Khronos WebCL" href="http://www.khronos.org/webcl/">WebCL</a></li>
<li><a title="W3C WebNotifications API Specification" href="http://dev.w3.org/2006/webapi/WebNotifications/">WebNotifications</a></li>
<li><a title="Google Web Intents Project" href="http://webintents.org/">Web Intents</a></li>
<li><a title="W3C Page Visibility API Specification" href="http://www.w3.org/TR/2011/WD-page-visibility-20110602/">Page Visibility</a></li>
<li><a title="Google requestAnimationFrame Proposal" href="http://webstuff.nfshost.com/anim-timing/Overview.html">requestAnimationFrame</a></li>
<li><a title="W3C Microdata specification" href="http://www.w3.org/TR/microdata/">Microdata</a></li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=375</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Processing arrays using CPS</title>
		<link>http://blog.n01se.net/?p=362</link>
		<comments>http://blog.n01se.net/?p=362#comments</comments>
		<pubDate>Thu, 04 Aug 2011 20:55:55 +0000</pubDate>
		<dc:creator>Chouser</dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=362</guid>
		<description><![CDATA[At work, we're generating JavaScript from another language (which ironically has nothing at all to do with ClojureScript). There are places where we are working with sequences of data, which generally originate with an array or more often arrays nested in other arrays (perhaps with intervening objects). As these sequences get built up and passed [...]]]></description>
			<content:encoded><![CDATA[<p>At <a title="Sentry Data Systems" href="http://www.sentryds.com/company/employment/">work</a>, we're generating JavaScript from another language (which ironically has nothing at all to do with <a href="http://clojure.com/blog/2011/07/22/introducing-clojurescript.html">ClojureScript</a>). There are places where we are working with sequences of data, which generally originate with an array or more often arrays nested in other arrays (perhaps with intervening objects). As these sequences get built up and passed around, layers of maps and filters get added until the desired result is correctly described. For example:</p>
<pre>﻿﻿﻿﻿    var input = [2, 4, 6, 8];
    var a = map(m3, filter(f2, map(m1, input)));</pre>
<p>where m3, f2, and m1 are various application-specific functions.  Again, just as an example, let's say:</p>
<pre>    ﻿function m1(x) { return x / 2; }
    function f2(x) { return x % 2 == 0; }
    function m3(x) { return x * 10; }</pre>
<p>That is, we want to divide everything in the input array by two, keep only even numbers from that, and multiply each of those by 10. Of course <code>map</code> and <code>filter</code> aren't standard JavaScript functions, so we have to write them.  The first dilemma in writing them is: what should they return?  Each could return an array, but then each stage will run through the entire sequence before the next stage starts, which seems undesirable if we can find any better way.  Another option would be for each to return a lazy sequence.  We've done this, including the required mechanisms for creating and examining <a href="http://clojure.org/">Clojure</a>-style <a title="Clojure docs for lazy-seq macro" href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/lazy-seq">lazy seqs</a>.  But this ends up creating a closure for every stage of every iteration. This causes us various problems such as memory leaks in buggy JS engines and failure to serialize lazy seqs to JSON.</p>
<p>So what other options exist?  I did say we're <em>generating</em> this JavaScript, so it's not actually a requirement that the code look as tidy as the snippet above, which puts <a title="Wikipedia: Continuation-passing style" href="http://en.wikipedia.org/wiki/Continuation-passing_style">continuation-passing style</a> on the table.  CPS is a style of API in which we don't use the return value of function, but instead pass in a function to be called once the result it known. If this reminds you of <a title="NodeJS events" href="http://nodejs.org/docs/v0.5.3/api/events.html#emitter.addListener">event</a>-<a title="jQuery events" href="http://api.jquery.com/bind/#multiple-events">handling</a> <a title="Dojo events" href="http://dojotoolkit.org/reference-guide/quickstart/events.html#events-available-for-connection">systems</a>, then good for you:</p>
<pre>    ﻿var a = [];
    forEach(input, function(x1) {
      cps_map(m1, x1, function(x2) {
        cps_filter(f2, x2, function(x2) {
          cps_map(m3, x2, function(x3) {
            a.push(x3); })})})});</pre>
<p>A few things to note here:</p>
<ol>
<li>The order in which the steps appear is reversed here compared to the earlier one-liner.  The ordering here feels more imperative and is arguably more comfortable. "For each of these, map with m1, then filter with f2, then map with m3, and finally push the results into array a"</li>
<li>The <code>cps_map</code> and <code>cps_filter</code> functions are not identical in responsibility to the earlier <code>map</code> and <code>filter</code> functions. Specifically, these do not have loops of their own but expect to be called repeatedly if necessary by earlier steps. This isn't part of translating them to CPS, but rather part of trying to avoid looping across the same sequence multiple times.</li>
<li>Despite points 1 and 2, we still have abstracted out the loop, map, and filter work so that we can refer to these operations by their names instead of re-implementing them.  That is, we didn't have to write our own <code>for</code> loop for this case and instead are still using high-order functions.</li>
</ol>
<p>This solution doesn't walk through the sequence more than once, since only <code>forEach</code> has a loop. But does it still create a closure for each iteration of each step?  Well, that might depend.  Technically the anonymous functions aren't closures since they don't access anything except their arguments and globals, but I wouldn't be surprised if some JS engine allocated a new instance each time anyway.  We could re-write it so that all the functions are named and defined at the outer scope, but that would damage the readability even more. So instead of pursuing that rought, lets try out Google Closure compiler's advanced optimizations instead:</p>
<pre>    for(var a = [], b = [2, 4, 6, 8], c = 0;c &lt; b.length;++c) {
      var d = b[c] / 2;
      d % 2 == 0 &amp;&amp; a.push(d * 10)
    }</pre>
<p>No closures, in fact no functions defined at all.  Just one tight <code>for</code> loop. That's <em>nice</em>.</p>
<p>If you want to try this yourself, start with the <a href="https://gist.github.com/1126248">full code for my example</a>, and paste it into <a href="http://closure-compiler.appspot.com/">GClosure's compiler</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=362</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Regarding Cloud Storage</title>
		<link>http://blog.n01se.net/?p=335</link>
		<comments>http://blog.n01se.net/?p=335#comments</comments>
		<pubDate>Tue, 26 Jul 2011 20:05:18 +0000</pubDate>
		<dc:creator>kanaka</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Moore's Law]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=335</guid>
		<description><![CDATA[This post is inspired by a blog post by Larry Stewart about "Connected-only devices" (e.g. Google Chromebook) and the problem with cloud/remote storage. Larry argues that for many types of data there are fundamental reasons why local storage is better than storing data in the cloud. His reasons are: Storage is cheap, communications are not [...]]]></description>
			<content:encoded><![CDATA[<p>This post is inspired by a <a title="Connected-only devices (Larry Stewart)" href="http://www.stewart.org/larry/?p=235">blog post</a> by <a href="#larry">Larry Stewart</a> about "Connected-only devices" (e.g. Google Chromebook) and the problem with cloud/remote storage. Larry argues that for many types of data there are fundamental reasons why local storage is better than storing data in the cloud. His reasons are:</p>
<blockquote>
<ul>
<li>Storage is cheap, communications are not</li>
<li>Storage is low power, communications are not</li>
<li>Local storage always works, communications does not</li>
<li>My use of local storage is private, in the cloud there are watchers</li>
<li>Local operations have predictable performance, remote does not</li>
</ul>
</blockquote>
<p>Larry is correct about the current problems with "Connected-only devices" and cloud storage and he has identified some real problems/costs of cloud storage vs local storage. I'm going go further and identify some additional costs involved in the local vs cloud storage equation. These other costs are more dominant (in determining what choices people will make) and by considering them I think they reveal a interesting trend:</p>
<p style="padding-left: 30px">﻿﻿﻿﻿﻿<strong>There is a cross-over point where cloud data becomes cheaper than local data. </strong></p>
<p><strong></strong>The cross-over point varies for different people and different types of data and in many cases it has already been crossed.</p>
<p><strong>Storage/Network costs</strong>:</p>
<p>First lets look at some of the costs that Larry identified. It is well known that transistor density is currently doubling every 24 months or so. This principle is known as <a title="Moore's Law (Wikipedia)" href="http://en.wikipedia.org/wiki/Moores_law">Moore's Law</a>. Less well known is <a title="Butter's Law (Wikipedia)" href="http://en.wikipedia.org/wiki/Moore's_law#Other_formulations_and_similar_laws">Butter's Law</a> which states that the amount of data able to be sent per optical fiber doubles every 9 months and <a title="Nielsen's Law (Wikipedia)" href="http://en.wikipedia.org/wiki/Nielsen%27s_Law#Contributions">Nielsen's Law</a> which states that the maximum bandwidth available to home users will double every 21 months. On the storage side is <a title="Kryder's Law (wikipedia)" href="http://en.wikipedia.org/wiki/Mark_Kryder#Kryder.27s_Law">Kryder's Law</a> which states that storage density doubles every 12 months.</p>
<p>Network and storage capacities are following exponential curves just like transistor densities. Even if network capacity and user bandwidth were doubling at a much, much slower rate than storage capacity there would still be a cross-over point where cloud data becomes cheaper (in practice and for most people) than local data. This is because the most important factors to consider are not the raw resource costs, but rather the <strong>time cost</strong> and the <strong>cost of convenience lost</strong>.</p>
<p>A few thoughts before moving on:</p>
<ol>
<li>The doubling of storage density affects the cost of cloud storage too,  so it's not a cut and dry Moore vs Kryder argument.</li>
<li>The speed/latency of disk storage is not keeping up with capacity. Cloud storage systems often have a better answer for this than is available with local storage. For example, before the advent of Gmail, we used to have to wait for email searches to complete.</li>
<li>The relevant question is not "How much am I paying per bit?" rather "How much is it costing me to keep my email/pictures/music (insert data/media type) stored locally vs stored in the cloud?"</li>
<li>When I'm talking about cloud storage, I'm not referring to a remote cloud hard drive service like <a title="www.dropbox.com" href="http://www.dropbox.com">Dropbox</a>, I really mean a cloud service that is designed around a certain type of data such as <a title="mail.google.com" href="http://mail.google.com">Gmail</a> for email or <a title="github.com" href="https://github.com">Github</a> for source code, etc.</li>
</ol>
<p><strong>Time Cost</strong>:</p>
<p>Both local data and remote/cloud data have a time cost. The time cost for remote data is primarily waiting for access to my data to download/cache and be available/usable. The primary time cost for local data is time spent managing that data: backups, upgrades, organizing, permissions, etc.</p>
<p>The time cost of remote data is decreasing on an exponential curve (the smaller the file/media type, the sooner this becomes essentially a negligible cost). The time cost of managing local data certainly is not decreasing at anywhere near the same rate.</p>
<p><strong>Cost of Convenience Lost</strong>:</p>
<p>Both local data and remote/cloud data also have a lost convenience cost. For remote data, this lost convenience is any time I don't have reasonable Internet connectivity (or the service is down). Finding yourself in a location without Internet access is extremely annoying, but imagine how much worse the situation was just three years ago.</p>
<p>The convenience cost for local data is that few people have access to this local data once they leave their homes. If they do have access, then they have probably either turned their home into a personal remote data service (time cost) or they duplicate their data to all their mobile devices (time cost).</p>
<p>There is also a privacy/security cost, but unfortunately, I think for most people it is very hard to quantify and therefore irrelevant for their day-to-day decisions. Also, it could be argued that the average person's mis-managed Windows PC might be more exposed than the average cloud provider.</p>
<p><strong>The Cross-Over Point(s)</strong>:</p>
<p>The cross-over point has already happened for most Internet users with email, bank records, contact lists, etc. Anyone remember POP3 email?</p>
<p>For most younger people this cross-over has also already happened with pictures (Facebook, Picassa, etc) and music (Pandora, last.fm, Apple Cloud, Google Music, etc). For the younger crowd (and other early adopters) the cross-over will happen soon (if it hasn't already) with documents (Google Docs, Office 365), presentations (Scribd, Google Docs, Youtube), videos/movies (Youtube, Hulu, Netflix, etc), etc, etc.</p>
<p>Large connected-only devices like the Google Chromebook will reach the cross-over point much later because they add a significant additional cost to the equation: weight/reduced portability. It's certainly possible that large connected-only devices may be so premature that they will die and not be ressurected for well beyond when they would have otherwise reached the cross-over point of cost-effectiveness.</p>
<p>The trend towards remote/cloud storage is already well underway. Nearly everyone who uses the Internet uses cloud storage in one form or another and they will be using much more of it in the near future.</p>
<blockquote><p>"<a title="William Gibson (wikiquote)" href="http://en.wikiquote.org/wiki/William_Gibson#Quotes">The future is already here — it's just not very evenly distributed</a>."</p></blockquote>
<p>---</p>
<p><strong>PostScript</strong>:<br />
<a name="larry"> </a></p>
<p>I knew Larry while I worked at SiCortex. I have met few software engineers that are more brilliant than Larry. Whenever I think about <a title="Joel Spolsky - The Guerilla Guide to Hiring" href="//www.joelonsoftware.com/articles/GuerrillaInterviewing3.html">Joel Spolsky's famous post</a> about hiring poeple that are "<strong>1. Smart and 2. Get things done</strong>", Larry is one of the people that comes to mind for me. Thank you, Larry, for unknowingly spurring me on to write something I've been wanting to write for a while now.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=335</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A hack to rescue Super+P from gnome-settings-daemon</title>
		<link>http://blog.n01se.net/?p=314</link>
		<comments>http://blog.n01se.net/?p=314#comments</comments>
		<pubDate>Mon, 09 May 2011 04:01:48 +0000</pubDate>
		<dc:creator>agriffis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=314</guid>
		<description><![CDATA[I like using tabbed terminals, and I like using Super+N ("next") and Super+P ("previous") to switch between the tabs. These bindings have worked well for years, but recently Super+P stopped working for me. Google helped me find two related bug reports: Ubuntu bug #539477: Video out hot key sends super + p + return on [...]]]></description>
			<content:encoded><![CDATA[<p>I like using <a href="http://roxterm.sourceforge.net/">tabbed terminals</a>, and I like using Super+N ("next") and Super+P ("previous") to switch between the tabs. These bindings have worked well for years, but recently Super+P stopped working for me. Google helped me find two related bug reports:</p>
<ul>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/539477">Ubuntu bug #539477: Video out hot key sends super + p + return on many upcoming Dell &#038; HP systems</a></li>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/gnome-settings-daemon/+bug/694910">Ubuntu bug #694910: Regression: patch to bug 539477 breaks Super+P keybindings</a></li>
</ul>
<p>The nutshell: Recent <a href="http://git.gnome.org/browse/gnome-settings-daemon/log">gnome-settings-daemon</a> unconditionally binds Super+P to rescan the video outputs and possibly reconfigure them. (If you're wondering, "Super" is the Win key, usually located between Ctrl and Alt.) The reason gnome-settings-daemon creates this binding is that newer PC BIOSes send this keystroke when they detect a monitor being plugged into, or unplugged from, the computer. And why do they do that? Because that's the keystroke in Windows 7 to bring up the display configuration dialog! So gnome-settings-daemon is simultaneously catching the BIOS announcement of changes to the attached displays, and also protecting your applications from a stray keystroke (that would most likely result in a "p" being inserted into the blog post you're writing).</p>
<p>I can't blame the authors of gnome-settings-daemon &mdash; this situation is really <a href="http://www.osnews.com/story/23202/The_win_p_Mess_Will_Microsoft_Ever_Learn_">Microsoft's fault</a> &mdash; but in any case, I'd rather handle video configuration changes without the extra help (I can launch the dialog on my own, thanks) and I can tolerate the tiny risk of a "p" turning up somewhere I didn't expect. I just want to be allowed to bind Super+P to change terminal tabs as I have in the past.</p>
<p>So here's a hack that gets the job done. The trick is to create a keybinding before gnome-settings-daemon starts, thereby blocking gnome-settings-daemon from grabbing it. After gnome-settings-daemon starts, release the binding so it's available to other programs, in my case the terminal emulator. To accomplish this I'm using <a href="http://www.nongnu.org/xbindkeys/xbindkeys.html">xbindkeys</a>, which is available in <a href="https://admin.fedoraproject.org/pkgdb/acls/name/xbindkeys">Fedora</a> and <a href="http://packages.ubuntu.com/search?keywords=xbindkeys">Ubuntu</a>.</p>
<p>Most of the time the distribution starts GNOME directly; i.e. gdm launches gnome-session for you. In that case you have no opportunity to run xbindkeys before gnome-settings-daemon runs. However you can customize the startup of your X applications by creating an <tt>$HOME/.xsession</tt> script and configuring your distro to use it. For Ubuntu instructions, see <a href="https://help.ubuntu.com/community/CustomXSession">help.ubuntu.com</a>; on Fedora you need to <tt>yum install xorg-x11-xinit-session</tt> then choose "User Script" at the login screen.</p>
<p>The minimal <tt>.xsession</tt> to rescue Super+P from gnome-settings-daemon is:</p>
<pre class="brush:bash">
#!/bin/sh
xbindkeys -f $HOME/.xbindkeysrc-super+p
exec gnome-session
</pre>
<p>with the accompanying configuration:</p>
<pre class="brush:bash">
# $HOME/.xbindkeysrc-super+p
"pkill xbindkeys"
 mod4 + p
</pre>
<p>So xbindkeys grabs Super+P before gnome-settings-daemon runs, then goes away the first time you press the combo, leaving the key available to your programs.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=314</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performance of Javascript (Binary) Byte Arrays in Modern Browsers</title>
		<link>http://blog.n01se.net/?p=248</link>
		<comments>http://blog.n01se.net/?p=248#comments</comments>
		<pubDate>Mon, 18 Apr 2011 17:31:45 +0000</pubDate>
		<dc:creator>kanaka</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=248</guid>
		<description><![CDATA[﻿Excerpts]]></description>
			<content:encoded><![CDATA[<p>A little over a year ago I started the <a href="https://github.com/kanaka/noVNC">noVNC</a> project, an HTML5 VNC client. noVNC does a <em>lot</em> of processing of binary byte array data and so array performance is a large predictor of overall noVNC performance. I had high hopes that one of the new binary byte array data types accessible to Javascript (in modern browsers) would give noVNC a large performance boost. In this post I describe some of my results from testing these binary byte array types.</p>
<p>After reading the title, you may have thought: <strong>"Wait ... Javascript doesn't have binary byte arrays."</strong> Actually, not only does Javascript have access to binary byte arrays but there are two unique variants available (technically neither are part of ECMAScript yet).</p>
<h3>Jump list:</h3>
<ul>
<li><a href="#the_options">The Options</a></li>
<ul>
<li><a href="#typed_arrays">Typed Arrays</a></li>
<li><a href="#imagedata_arrays">ImageData arrays</a></li>
<li><a href="#traditional_solutions">Traditional Solutions</a></li>
</ul>
<li><a href="#bad_news">The Bad News</a></li>
<li><a href="#testing">Testing</a></li>
<ul>
<li><a href="#four_tests">The Four Tests</a></li>
<li><a href="#test_results">Test Results</a></li>
<li><a href="#test_result_summary">Test Result Summary</a></li>
</ul>
<li><a href="#browser_regressions">Browser Improvements/Regressions</a></li>
<ul>
<li><a href="#firefox">Firefox</a></li>
<li><a href="#chrome">Chrome</a></li>
<li><a href="#ie9">IE 9</a></li>
</ul>
<li><a href="#final_thoughts">Final Thoughts</a></li>
<ul>
<li><a href="#requests">Requests</a></li>
<li><a href="#followup">Followup Posts</a></li>
</ul>
<li><a href="#references">References</a></li>
</ul>
<p><a name="the_options"><br />
<h3>The Options</h3>
<p></a></p>
<p><a name="typed_arrays"><br />
<h4>Typed Arrays:</h4>
<p></a><br />
Those who follow browser development and HTML standardization may already be aware of one of these array types. ArrayBuffers (technically: <a href="http://www.khronos.org/registry/typedarray/specs/latest/">Typed Arrays</a>) are a required part of the proposed <a href="https://www.khronos.org/registry/webgl/specs/1.0/">WebGL</a> and <a href="http://www.w3.org/TR/FileAPI/">File API</a> standards. To use an ArrayBuffer as a byte array you create a Uint8Array view of the ArrayBuffer.</p>
<p>The following Javascript creates an ArrayBuffer view that contains 1000 unsigned byte elements that are initialized to 0:</p>
<pre style="padding-left: 30px">var arr = Uint8Array(new ArrayBuffer(1000));</pre>
<p><a name="imagedata_arrays"><br />
<h4>ImageData arrays:</h4>
<p></a><br />
But there is an older and more widely supported form of binary byte arrays available to Javascript programs: ImageData. ImageData is a data type that is defined as part of the 2D context of the Canvas element. ImageData is created whenever the getImageData or createImageData method is invoked on a Canvas 2D context. The "data" attribute of an ImageData object is a byte array that is 4 times larger than the width * height requested (4 bytes of R,G,B,A for each pixel).</p>
<p>The following Javascript creates a ImageData byte array with 1000 unsigned byte elements that are initialized to 0:</p>
<pre style="padding-left: 30px">var ctx = getElementById('canvas').getContext('2d'),
arr = ctx.createImageData(25, 10).data;</pre>
<p><a name="traditional_solutions"><br />
<h4>Traditional Solutions:</h4>
<p></a><br />
There are two traditional ways of representing binary byte data in Javascript. The first is with a normal Javascript array where every element of array is a number in the range 0 through 255. The second method is using a string in which the values 0 through 255 are stored as Unicode characters in the string and read using the charCodeAt method. For this post I'm going to ignore the string method since Javascript strings are immutable and updating a single character in a Javascript string implies reconstructing the whole string which is both unpleasant and slow.</p>
<p>The following creates a normal Javascript array with 1000 numbers that are initialized to 0:</p>
<pre style="padding-left: 30px">var arr = [], i;
for (i = 0; i &lt; 1000; arr[i++] = 0) {}</pre>
<p><a name="bad_news"><br />
<h3>The Bad News</h3>
<p></a><br />
We are left with three methods for representing binary byte data: normal Javascript arrays, ImageData arrays, and ArrayBuffer arrays. One might expect that since ImageData and ArrayBuffer arrays are fixed sized, have elements with a fixed type, and are used for performance sensitive operations (2D canvas and WebGL) that the performance of these native byte arrays would be better than normal Javascript arrays for most operations. Unfortunately, as of today, most operations are slower when using these byte array types.</p>
<p><a name="testing"><br />
<h3>Testing</h3>
<p></a><br />
Originally I planned to show the performance numbers comparing browsers on Linux and Windows. However, I discovered that there is very little difference (for these array tests) between the same version of a browser running on Windows vs Linux. Since all the Linux browsers also run on Windows (but not vice versa) I have limited the performance results to Windows.</p>
<p>For this post I have hacked together four quick tests to compare normal Javascript arrays with ImageData and ArrayBuffer arrays. All the tests use arrays that contain 10240 (10 * 1024) elements and repeat the operation being tested many times in order to push the test times into a more easily measured and comparable range. Each test is also run 10 times (iterations) and the mean and standard deviation across all 10 iterations is calculated.</p>
<p>You can run tests yourself by cloning the <a href="https://github.com/kanaka/noVNC">noVNC repository</a> and loading the <em>tests/arrays.html</em> page. These test results are based on revision bbee8098 of noVNC. Running the test in a browser will output JSON data in the results textarea. This JSON data can then be combined with JSON data from other browser results and run through the <em>utils/json2graph.py</em> python script which uses the matplotlib module to generate the graphs.</p>
<p>The test machine has the following specifications:</p>
<ul>
<li>Acer Aspire 5253-BZ893</li>
<li>AMD Dual-Core C50 at 1GHz</li>
<li>3GB DDR3 Memory</li>
<li>AMD Radeon HD 6250</li>
<li>Windows 7</li>
</ul>
<p>Here are the main browsers that were tested:</p>
<ul>
<li><a href="http://build.chromium.org/f/chromium/snapshots/chromium-rel-xp/">Chrome 12.0.716.0 (build 79495)</a></li>
<li><a href="http://windows.microsoft.com/en-US/internet-explorer/downloads/ie">IE 9.0.8112.16421 64-bit</a></li>
<li><a href="http://www.mozilla.com/en-US/firefox/beta/">Firefox 4.0</a></li>
<li><a href="http://www.opera.com/browser/">Opera 11.01</a></li>
</ul>
<p>In addition, older browser versions were also tested to see if the browsers are making progress:</p>
<ul>
<li>Chrome 9.0.597.98</li>
<li>Chrome 10.0.648.204</li>
<li>Chrome 11.0.673.0 (build 75038)</li>
<li>IE 9.0 Platform Preview 7</li>
<li>Firefox 3.6.13</li>
<li>Firefox 3.6.16</li>
<li>Firefox 4.0 beta 11</li>
</ul>
<p>Please note that I am not a professional performance tester so I probably haven't made use of optimal testing techniques and there is certainly a possibility that I have made mistakes that invalidate some or all of the numbers. I welcome constructive criticism and dialog so that I can expand and improve on these results in the future.</p>
<p><a name="four_tests"><br />
<h4>The Four Tests:</h4>
<p></a></p>
<ol>
<li><strong>create</strong> - For each test iteration, an array is created and then initialized to zero and this is repeated 2000 times.</li>
<li><strong>randomRead</strong> - For each test iteration, 5 million reads are issued to pseudo-random locations in an array.</li>
<li><strong>sequentialRead</strong> - For each test iteration, 5 million reads are issued sequentially to an array. The reads loop around to the beginning of the array when they reach the end of the array.</li>
<li><strong>sequentialRead</strong> - For each test iteration, 5 million updates are made sequentially to an array. The writes loop around to the beginning of the array when they reach the end of the array.</li>
</ol>
<p><a name="test_results"><br />
<h4>Test Results:</h4>
<p></a><br />
First let's take a look at how the different array types perform at the different tests.</p>
<div id="attachment_280" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/create.png"><img class="size-full wp-image-280  " src="http://blog.n01se.net/wp-content/uploads/2011/04/create.png" alt="Create Test Results" width="486" height="294" /></a><p class="wp-caption-text">Create Test Results</p></div>
<p style="text-align: center">
<p>This is the only test where ImageData and ArrayBuffer arrays have a significant performance advantage because they are automatically initialized to 0 when created. IE 9 and Opera do not currently support ArrayBuffer arrays.</p>
<div id="attachment_250" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/randRead.png"><img class="size-full wp-image-250   " src="http://blog.n01se.net/wp-content/uploads/2011/04/randRead.png" alt="Javascript binary array random read test" width="486" height="294" /></a><p class="wp-caption-text">Random Read Test Results</p></div>
<p>Chrome and Opera have the best overall performance although Opera does not support ArrayBuffer arrays yet. Firefox has particularly bad random read performance across the board. The results show that there is little advantage to using ImageData or ArrayBuffer arrays for random reads and their performance in Chrome and Opera is significantly slower.</p>
<div id="attachment_253" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/seqRead.png"><img class="size-full wp-image-253  " src="http://blog.n01se.net/wp-content/uploads/2011/04/seqRead.png" alt="Sequential Read Test" width="486" height="294" /></a><p class="wp-caption-text">Sequential Read Test Results</p></div>
<p>For the sequential read test the situation is quite different. Firefox has consistent and leading performance across all array types. Chrome has an order of magnitude worse performance for ImageData and ArrayBuffer arrays. Opera 11 show a 3X fall in performance for ImageData arrays compared to normal Javascript arrays. Normal arrays are still the best choice overall.</p>
<div id="attachment_254" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/seqWrite.png"><img class="size-full wp-image-254  " src="http://blog.n01se.net/wp-content/uploads/2011/04/seqWrite.png" alt="Sequential Write Test" width="486" height="294" /></a><p class="wp-caption-text">Sequential Write Test Results</p></div>
<p>The sequential write test relative results are very similar to sequential reads with a slow down across the board. Firefox again shows comparable performance across all three array types. Opera 11 continues to show a 3X fall in performance with ImageData arrays. Chrome continues to show an order of magnitude speed different between normal arrays and the binary arrays.</p>
<hr />Now let's slice the data differently to see how the different browsers compare across the different array types.</p>
<div id="attachment_255" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/normal.png"><img class="size-full wp-image-255   " src="http://blog.n01se.net/wp-content/uploads/2011/04/normal.png" alt="Normal Array Test Results" width="486" height="294" /></a><p class="wp-caption-text">Normal Array Test Results</p></div>
<p>Chrome is the best overall performer here with Opera pulling a close second. However, the most notable result in this view is the terrible performance of Firefox random reads. Given the huge amount of jitter in the Firefox result compared to the others, my guess is this is a degenerate case and that Mozilla has some low hanging fruit here.</p>
<div id="attachment_256" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/imageData.png"><img class="size-full wp-image-256   " src="http://blog.n01se.net/wp-content/uploads/2011/04/imageData.png" alt="ImageData Test Results" width="486" height="294" /></a><p class="wp-caption-text">ImageData Test Results</p></div>
<p>Opera is now the overall performance winner with Chrome pulling a close second. The Firefox problem with random reads continues to show up with ImageData arrays (although this time without the jitter). Excluding the random read result, Firefox would be the clear winner. IE 9 has a good showing here coming in a close third overall.</p>
<div id="attachment_257" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/arrayBuffer.png"><img class="size-full wp-image-257    " src="http://blog.n01se.net/wp-content/uploads/2011/04/arrayBuffer.png" alt="ArrayBuffer Test Results" width="486" height="294" /></a><p class="wp-caption-text">ArrayBuffer Test Results</p></div>
<p>The pack thins out significantly since only Chrome and Firefox support ArrayBuffers. Once again Firefox shows pessimal random read performance. With that result excluded (or fixed), Firefox would be the clear winner against Chrome.</p>
<p><a name="test_result_summary"><br />
<h4>Test Result Summary:</h4>
<p></a></p>
<ul>
<li>Chrome has the best overall performance for normal arrays.</li>
<li>Opera has the best overall performance for ImageData arrays with Chrome a close second.</li>
<li>Firefox has good performance except for random reads where performance drops off a cliff on all array types.</li>
</ul>
<p><a name="browser_regressions"><br />
<h3>Browser Improvements/Regressions</h3>
<p></a><br />
Now we will compare some older browser versions to see if the browser vendors are making progress over time in improving the performance of the binary byte array types.</p>
<p><a name="firefox"><br />
<h4>Firefox</h4>
<p></a><br />
<div id="attachment_291" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/ff_normal.png"><img class="size-full wp-image-291  " src="http://blog.n01se.net/wp-content/uploads/2011/04/ff_normal.png" alt="Normal Array Test Results for Firefox" width="486" height="294" /></a><p class="wp-caption-text">Normal Array Test Results for Firefox</p></div></p>
<p>Firefox mostly shows steady improvement for normal arrays, but once again the terrible random read perform rears its head in the shift from 4.0 beta 11 to the 4.0 release version.</p>
<div id="attachment_290" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/ff_imageData.png"><img class="size-full wp-image-290 " src="http://blog.n01se.net/wp-content/uploads/2011/04/ff_imageData.png" alt="ImageData Test Results for Firefox" width="486" height="294" /></a><p class="wp-caption-text">ImageData Test Results for Firefox</p></div>
<p>Again, Firefox mostly shows steady improvement for ImageData arrays. This time the terrible random read performance was introduced somewhere between the Firefox 3 and Firefox 4 code base.</p>
<div id="attachment_289" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/ff_arayBuffer.png"><img class="size-full wp-image-289 " src="http://blog.n01se.net/wp-content/uploads/2011/04/ff_arayBuffer.png" alt="ArrayBuffer Test Results for Firefox" width="486" height="294" /></a><p class="wp-caption-text">ArrayBuffer Test Results for Firefox</p></div>
<p>Only Firefox 4 supports ArrayBuffer arrays. The awful random read performance still exists.</p>
<p><a name="chrome"><br />
<h4>Chrome</h4>
<p></a><br />
<div id="attachment_288" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_normal.png"><img class="size-full wp-image-288 " src="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_normal.png" alt="Normal Array Test Results for Chrome" width="486" height="294" /></a><p class="wp-caption-text">Normal Array Test Results for Chrome</p></div></p>
<p>No strong trends appear in the Chrome data for normal arrays. The array create speed shows a significant dropoff in Chrome 12. For sequential writes there was a 2X regression for Chrome 10 and 11.</p>
<div id="attachment_287" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_imageData.png"><img class="size-full wp-image-287 " src="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_imageData.png" alt="ImageData Test Results for Chrome" width="486" height="294" /></a><p class="wp-caption-text">ImageData Test Results for Chrome</p></div>
<p>There appears to be a significant regression in Chrome 12 related to ImageData performance. The amount of the dropoff (3X to 6X) and the significant jitter indicate to me that their is a obvious propblem that should be fixed.</p>
<div id="attachment_286" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_arrayBuffer.png"><img class="size-full wp-image-286 " src="http://blog.n01se.net/wp-content/uploads/2011/04/chrome_arrayBuffer.png" alt="ArrayBuffer Test Results for Chrome" width="486" height="294" /></a><p class="wp-caption-text">ArrayBuffer Test Results for Chrome</p></div>
<p>There are no strong trends in Chrome ArrayBuffer array performance although there seems to be a weak trend towards worse performance.</p>
<p><a name="ie9"><br />
<h4>IE 9</h4>
<p></a><br />
<div id="attachment_293" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/ie_normal.png"><img class="size-full wp-image-293 " src="http://blog.n01se.net/wp-content/uploads/2011/04/ie_normal.png" alt="Normal Array Test Results for Internet Explorer" width="486" height="294" /></a><p class="wp-caption-text">Normal Array Test Results for Internet Explorer</p></div></p>
<div id="attachment_292" class="wp-caption aligncenter" style="width: 496px"><a href="http://blog.n01se.net/wp-content/uploads/2011/04/ie_imageData.png"><img class="size-full wp-image-292 " src="http://blog.n01se.net/wp-content/uploads/2011/04/ie_imageData.png" alt="ImageData Test Results for Internet Explorer" width="486" height="294" /></a><p class="wp-caption-text">ImageData Test Results for Internet Explorer</p></div>
<p>The final release of IE9 shows a <em>huge</em> performance decrease compared to the Platform Preview 7. If Microsoft is able to recover this performance in a subsequent release then this would significantly change the standing of IE 9 in relation to the other modern browsers.</p>
<p><a name="final_thoughts"><br />
<h3>Final Thoughts</h3>
<p></a><br />
ImageData and ArrayBuffer arrays have different performance characteristics within the same browsers. I'm not sure why this should be the case. In fact, <strong>I would recommend that the WHATWG/W3C and browser vendors standardize on ArrayBuffers for both purposes</strong>. This could be done by adding an additional attribute to the ImageData object perhaps named 'buffer'. The new 'buffer' attribute would be a generic ArrayBuffer containing the the image data memory. The existing 'data' attribute would become a Uint8Array view of the ArrayBuffer (this would maintain backwards compatibility). In addition to code consolidation within the browsers (and one place to focus optimization effort) this change would allow developers to create a Uint32Array view of the buffer which would allow whole pixel updates (3 colors + alpha) with one operation.</p>
<p>Using ImageData and ArrayBuffer (typed array view) arrays will generally not give better performance for binary byte data than just using normal Javascript arrays. This is unfortunate since these binary array types exist specifically to serve performance sensitive functionality (2D and 3D graphics). It is also surprising since they have a fixed size and a fixed element type which in theory should allow faster read and write access to the elements. I suspect (and hope) that this performance problem is due to the fact that <strong>not enough optimization effort has been applied by any of the browser vendors to these binary arrays</strong>.</p>
<p><a name="requests"><br />
<h4>Requests:</h4>
<p></a></p>
<ul>
<li>Mozilla, Google (and Apple), Microsoft and Opera: please spend some effort to <strong>optimize your Javascript binary array types!</strong></li>
<li>Microsoft and Opera: it would be nice if you would implement WebGL. But if not, please at least <strong>implement typed array (ArrayBuffer) support</strong> since it stands on its own and will likely be used in the near future in other places where it make sense such as FileReader objects and in the WebSocket API to support binary data.</li>
</ul>
<p><a name="followup"><br />
<h4>Followup Posts:</h4>
<p></a><br />
The browser wars are back and new browsers versions are being released every few weeks. My plan is to continue updating these tests to include the most recent browser versions. I would also like to expand the tests to include a random write test and also to test the random and sequential read performance of binary data stored in Javascript strings. Stay tuned.</p>
<p><a name="references"><br />
<h3>References</h3>
<p></a></p>
<ul>
<li><a href="https://github.com/kanaka/noVNC">noVNC</a></li>
<li><a href="http://matplotlib.sourceforge.net/">matplotlib python module</a></li>
<li><a href="https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/TypedArray-spec.html">Typed Array (ArrayBuffer) Specification</a></li>
<li><a href="https://developer.mozilla.org/en/JavaScript_typed_arrays">MDN Typed Array Page</a></li>
<li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata">ImageData spec section</a></li>
<li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspixelarray">CanvasPixelArray spec section</a></li>
<li><a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas">MDN Canvas pixel manipulation page</a></li>
<li><a href="http://www.w3.org/TR/FileAPI/#FileReader-interface">FileReader spec</a></li>
<li><a href="https://developer.mozilla.org/en/DOM/FileReader">MDN FileReader Page</a></li>
<li><a href="http://dev.w3.org/html5/websockets/">WebSocket API spec</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=248</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Weekend hack: multitouch drawing on iPhone</title>
		<link>http://blog.n01se.net/?p=237</link>
		<comments>http://blog.n01se.net/?p=237#comments</comments>
		<pubDate>Mon, 10 Jan 2011 21:28:27 +0000</pubDate>
		<dc:creator>Chouser</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=237</guid>
		<description><![CDATA[I played around with the multitouch browser API and the HTML5 canvas tag this weekend, and came up with a little drawing page for the iPhone.  The slower you drag your finger across the screen, the fatter the line will be. If you use multiple fingers at once, each should produce its own line with [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" title="Screenshot of Drawing" src="http://chouser.github.com/draw/snap.jpg" alt="" width="192" height="288" />I played around with the multitouch browser API and the HTML5 canvas tag this weekend, and came up with a little <a href="http://chouser.github.com/draw">drawing page</a> for the iPhone.  The slower you drag your finger across the screen, the fatter the line will be. If you use multiple fingers at once, each should produce its own line with its own color. Note that you must use a touch-screen device; there's no mouse support at all. Also, there's no way to control the color yourself, and the only way to clear the screen is to reload the page.</p>
<p>The screenshot on the right was taken after clicking on the little "plus" button in Safari and adding the page to my "home screen", then launching the page from there. This gets rid of the URL bar, so that you can have more empty black space above your carefully drawn portraits.</p>
<p>I only tested it on my iPhone 3G, but it ought to work on any iOS device. Please comment if you notice it fails on an Apple touch device or if it works on anything else.</p>
<p>I count the project as a success because my three-year-old now prefers this to the little drawing app she used to use on my phone, and mine of course doesn't have any ads.</p>
<p>Feel free to use <a href="https://github.com/Chouser/chouser.github.com/blob/master/draw/index.html">the 110 or so lines of code</a> however you'd like.</p>
<p><em>Update: </em>I received a report that it works on the Droid.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=237</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to capture httplib2 debug in a threaded app</title>
		<link>http://blog.n01se.net/?p=218</link>
		<comments>http://blog.n01se.net/?p=218#comments</comments>
		<pubDate>Sun, 29 Aug 2010 20:06:35 +0000</pubDate>
		<dc:creator>agriffis</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[httplib]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=218</guid>
		<description><![CDATA[A couple months ago I blogged about my frustration with httplib logging. Andrew Dalke left a comment suggesting that I should replace sys.stdout, something I hadn't considered as a possibility. His suggestion sent me googling, which turned up this old email from Guido. Add threading.local and we have a solution! What we need is a [...]]]></description>
			<content:encoded><![CDATA[<p>A couple months ago I blogged about <a href="http://blog.n01se.net/?p=213">my frustration with httplib logging</a>. Andrew Dalke <a href="http://blog.n01se.net/?p=213#comment-2315">left a comment</a> suggesting that I should replace <a href="http://docs.python.org/library/sys.html#sys.stdout">sys.stdout</a>, something I hadn't considered as a possibility. His suggestion sent me googling, which turned up this <a href="http://n01se.net/paste/sM72">old email from Guido</a>. Add <a href="http://docs.python.org/library/threading.html#threading.local">threading.local</a> and we have a solution!</p>
<p>What we need is a duck-typed replacement for sys.stdout that behaves like a writeable file, but also provides the ability to capture to thread-local storage. One of the ways to use threading.local is to subclass it. An instance of this subclass will have per-thread attributes, even if the instance itself is common to multiple threads.</p>
<p>Since <a href="http://docs.python.org/library/stringio.html">StringIO</a> intentionally doesn't implement isatty(), we need to make sure that gets passed through to the underlying file (we do this by catching the exception in getattr). And since we like seeing HTTP transactions when we're debugging, we include a writethrough mode that provides simultaneous capture and print.</p>
<pre class="brush:python;gutter:false">
import cStringIO, threading

class LocalCapturingWriter(threading.local):
    def __init__(self, fp, writethrough=False):
        self.__dict__['_fp'] = fp
        self.__dict__['_stringio'] = None
        self.__dict__['_writethrough'] = writethrough

    def start_capture(self):
        self.__dict__['_stringio'] = cStringIO.StringIO()

    def stop_capture(self):
        v = self._stringio.getvalue()
        self._stringio.close()
        self.__dict__['_stringio'] = None
        return v

    def write(self, s):
        if self._stringio:
            result = self._stringio.write(s)
        if not self._stringio or self._writethrough:
            result = self._fp.write(s)
        return result

    def __getattr__(self, name):
        if self._stringio is not None:
            try:
                return getattr(self._stringio, name)
            except:
                pass
        return getattr(self._fp, name)

    def __setattr__(self, name, value):
        if self._stringio:
            setattr(self._stringio, name, value)
        if not self._stringio or self._writethrough:
            setattr(self._fp, name, value)
</pre>
<p>And here's how to use it. First, the global settings:</p>
<pre class="brush:python;gutter:false">
import httplib2, sys

httplib2.debuglevel = 1

sys.stdout = LocalCapturingWriter(sys.stdout)
</pre>
<p>Then the code that runs in a thread to capture the debugging output. This will work as expected even in multiple threads simultaneously.</p>
<pre class="brush:python;gutter:false">
sys.stdout.start_capture()
try:
    response, content = \
        httplib2.Http().request("http://n01se.net")
finally:
    debug_trace = sys.stdout.stop_capture()

# Note that httplib2 doesn't include the content in its
# debug output.
debug_trace += "content: %r\n" % content
</pre>
<p>We're now using this in our Django app, with a custom Exception class (to hold the captured trace) and middleware that knows to look for it. The end result is that every time an exception occurs due to a problem talking to a backend server, the exception email includes the httplib2 trace. Yeah!</p>
<p>P.S. I wrote this entry less than a week after my previous entry, but then went on vacation and never managed to get it posted. Sorry for the delay...</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=218</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python&#8217;s httplib uses print for debugging. Oh, it hurts&#8230;</title>
		<link>http://blog.n01se.net/?p=213</link>
		<comments>http://blog.n01se.net/?p=213#comments</comments>
		<pubDate>Sun, 04 Jul 2010 18:12:24 +0000</pubDate>
		<dc:creator>agriffis</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[grumpy]]></category>
		<category><![CDATA[httplib]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=213</guid>
		<description><![CDATA[At work we have a production site that uses httplib (via httplib2) on the server to communicate with internal servers using a RESTful API. When something doesn't work as expected in this process, we like to know about it, so our app sends email with the exception traceback and whatever relevant data we can pull [...]]]></description>
			<content:encoded><![CDATA[<p>At work we have a production site that uses httplib (via httplib2) on the server to communicate with internal servers using a RESTful API. When something doesn't work as expected in this process, we like to know about it, so our app sends email with the exception traceback and whatever relevant data we can pull together.</p>
<p>One of the pieces of data I'd like to add to the email is the conversation between our server and the internal servers. On a development server, this is easy: Set httplib2.debuglevel=1 and watch the HTTP conversations scroll past on stdout.</p>
<p>On a staging or production server, one quickly discovers a crippling mistake made by the httplib authors: the library uses Python's "print" for debugging!</p>
<p>If the application were single-threaded, we could capture the trace by temporarily redirecting sys.stdout to an instance of StringIO (maybe using a context manager). Sure, it's more load on the server to capture the debug on every transaction, but I'll gladly pay that price for the hours we'll save when something goes wrong and we have the ability to debug it.</p>
<p>But it doesn't matter, because we haven't this option. Our app is multi-threaded and sys.stdout is global. We would have to serialize our HTTP transactions to prevent traces from being mixed together. Or fork to isolate sys.stdout. These aren't realistic approaches.</p>
<p>This sort of unfortunate shortcoming is to be expected in add-on libraries. After all, part of the reason they're not included with Python is that they don't necessarily meet the quality requirements of the core distribution. But I'm taken off-guard to find such an obvious shortcoming in the Python standard library. One of the things I'd hope to assume by using the standard library is a trust in the quality of the implementation, but a discovery like this forces me to question that assumption.</p>
<p>I'm pretty new to Python, so maybe I'm missing something. Is httplib a particularly poor example of the Python standard library? The existence of httplib2 seems to imply that (and also seems to imply that it's hard to get problems fixed in the core distribution). Maybe I need to find an add-on networking library that ignores httplib entirely...?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=213</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>a common css mistake</title>
		<link>http://blog.n01se.net/?p=203</link>
		<comments>http://blog.n01se.net/?p=203#comments</comments>
		<pubDate>Sat, 15 May 2010 03:39:13 +0000</pubDate>
		<dc:creator>agriffis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.n01se.net/?p=203</guid>
		<description><![CDATA[I'm playing with febootstrap this evening, part of a continuing migration away from Ubuntu toward Debian and Fedora. I googled my way to Rich's febootstrap page. On my browser, it looks like this: The problem is that the page's css has the following rules: h1, h2, h3, h4 { color: #333; } pre { background-color: [...]]]></description>
			<content:encoded><![CDATA[<p>I'm playing with febootstrap this evening, part of a continuing migration away from Ubuntu toward Debian and Fedora. I googled my way to <a href="http://people.redhat.com/~rjones/febootstrap/">Rich's febootstrap page</a>. On my browser, it looks like this:</p>
<p><a href="http://blog.n01se.net/wp-content/uploads/2010/05/febootstrap-css-mistake2.png"><img src="http://blog.n01se.net/wp-content/uploads/2010/05/febootstrap-css-mistake2-e1273894578460.png" alt="" title="febootstrap-css-mistake" width="399" height="256" class="aligncenter size-full wp-image-209" /></a></p>
<p>The problem is that the page's css has the following rules:</p>
<pre class="brush:css;gutter:false">
h1, h2, h3, h4 {
  color: #333;
}

pre {
  background-color: #fcfcfc;
}
</pre>
<p>Both these rules assume the usual black-on-white color scheme, but I'm using a gtk theme with a dark background and light foreground, which firefox respects.  (Chromium doesn't have the issue because it enforces black-on-white defaults regardless of the gtk theme. I'm not sure how I feel about that; it fixes the problem but at the expense of ignoring my theme.)</p>
<p>This isn't to say anything bad about febootstrap, of course. I'm thrilled that somebody has finally written for Fedora what the excellent debootstrap has been providing for Debian and Ubuntu users for years! But I've come across this mistake enough times that Rich's site drew the unlucky number. <img src='http://blog.n01se.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.n01se.net/?feed=rss2&#038;p=203</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.542 seconds -->
<!-- Cached page served by WP-Cache -->

