<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> 

  <title>Erik Rigtorp</title>
  <link href="http://www.rigtorp.se/atom.xml" rel="self"/>
  <link href="http://www.rigtorp.se/"/>
  <updated>2011-01-01T23:40:21-05:00</updated>
  <id>http://rigtorp.se/</id>
  <author>
    <name>Erik Rigtorp</name>
    <email>erik@rigtorp.com</email>
  </author>

  
  <entry>
    <title>Efficient rolling statistics with NumPy</title>
    <link href="http://www.rigtorp.se/2011/01/01/rolling-statistics-numpy.html"/>
    <updated>2011-01-01T00:00:00-05:00</updated>
    <id>http://www.rigtorp.se/2011/01/01/rolling-statistics-numpy</id>
    <content type="html">&lt;h1 id='efficient_rolling_statistics_with_numpy'&gt;Efficient rolling statistics with NumPy&lt;/h1&gt;

&lt;p&gt;When working with time series data with &lt;a href='http://www.scipy.org'&gt;NumPy&lt;/a&gt; I often find myself needing to compute &lt;em&gt;rolling&lt;/em&gt; or &lt;em&gt;moving&lt;/em&gt; statistics such as mean and standard deviation. The simplest way compute that is to use a for loop:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;rolling_apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;fun&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='n'&gt;r&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;np&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;empty&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;fill&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;np&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nan&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='nb'&gt;range&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]):&lt;/span&gt;
        &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;fun&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A loop in &lt;a href='http://www.python.org'&gt;Python&lt;/a&gt; are however very slow compared to a loop in C code. Fortunately there is a trick to make NumPy perform this looping internally in C code. This is achieved by adding an extra dimension with the same size as the window and an appropriate &lt;a href='http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html'&gt;stride&lt;/a&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;rolling_window&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;window&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='n'&gt;shape&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='p'&gt;[:&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;window&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;window&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;strides&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strides&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strides&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;np&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;lib&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;stride_tricks&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;as_strided&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;shape&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;strides&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;strides&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Using this function it is easy to calculate for example a rolling mean without looping in Python:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;np&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;arange&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;reshape&lt;/span&gt;&lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;rolling_window&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='p'&gt;([[[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;]],&lt;/span&gt;
       &lt;span class='p'&gt;[[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;]]])&lt;/span&gt;
    
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;np&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;mean&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;rolling_window&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='p'&gt;([[&lt;/span&gt; &lt;span class='mf'&gt;1.&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mf'&gt;2.&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mf'&gt;3.&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
       &lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='mf'&gt;6.&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mf'&gt;7.&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mf'&gt;8.&lt;/span&gt;&lt;span class='p'&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;More about the &amp;#8220;stride trick&amp;#8221;: &lt;a href='http://www.scipy.org/Cookbook/SegmentAxis'&gt;SegmentAxis&lt;/a&gt;, &lt;a href='http://www.scipy.org/Cookbook/GameOfLifeStrides'&gt;GameOfLifeStrides&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Automatically generating Erlang release files</title>
    <link href="http://www.rigtorp.se/2010/03/17/generate-erlang-rel.html"/>
    <updated>2010-03-17T00:00:00-04:00</updated>
    <id>http://www.rigtorp.se/2010/03/17/generate-erlang-rel</id>
    <content type="html">&lt;h1 id='automatically_generating_erlang_release_files'&gt;Automatically generating Erlang release files&lt;/h1&gt;

&lt;p&gt;If you&amp;#8217;ve ever worked with &lt;a href='http://erlang.org'&gt;Erlang&lt;/a&gt; and worked with it&amp;#8217;s release handling functionality you&amp;#8217;ve probably been frustrated by the requirement to explicitly specify version numbers of applications included in the &lt;a href='http://ftp.sunet.se/pub/lang/erlang/doc/design_principles/release_structure.html'&gt;&lt;em&gt;release resource file&lt;/em&gt;&lt;/a&gt; (&lt;code&gt;.rel&lt;/code&gt; file). I understand why it is useful to specify application version explicity when you are make a release for a specific target platform, but in many cases you want to use the version currently installed on your system.&lt;/p&gt;

&lt;p&gt;In order to make it easier to create a release file and boot script I created a &lt;code&gt;make&lt;/code&gt; target to automatically generate these from an &lt;a href='http://www.erlang.org/doc/design_principles/applications.html'&gt;&lt;em&gt;application resource file&lt;/em&gt;&lt;/a&gt; (&lt;code&gt;.app&lt;/code&gt; file):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='make'&gt;&lt;span class='k'&gt;$(&lt;/span&gt;APP&lt;span class='k'&gt;)&lt;/span&gt;.boot: &lt;span class='k'&gt;$(&lt;/span&gt;APP&lt;span class='k'&gt;)&lt;/span&gt;.rel Makefile
	&lt;span class='k'&gt;$(&lt;/span&gt;ERL&lt;span class='k'&gt;)&lt;/span&gt; -pa ebin -noshell +B -eval &lt;span class='se'&gt;\&lt;/span&gt;
	&lt;span class='s1'&gt;&amp;#39;case systools:make_script(&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class='k'&gt;$(&lt;/span&gt;basename &lt;span class='nv'&gt;$@&lt;/span&gt;&lt;span class='k'&gt;)&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;quot;,[local]) of \&lt;/span&gt;
&lt;span class='s1'&gt;         ok -&amp;gt; halt(0); _ -&amp;gt; halt(1) end.&amp;#39;&lt;/span&gt;

&lt;span class='k'&gt;$(&lt;/span&gt;APP&lt;span class='k'&gt;)&lt;/span&gt;.rel: ebin/&lt;span class='k'&gt;$(&lt;/span&gt;APP&lt;span class='k'&gt;)&lt;/span&gt;.app Makefile
	&lt;span class='k'&gt;$(&lt;/span&gt;ERL&lt;span class='k'&gt;)&lt;/span&gt; -pa ebin -noshell +B -eval &lt;span class='se'&gt;\&lt;/span&gt;
	&lt;span class='s2'&gt;&amp;quot;ok = application:load($(basename $@)), \&lt;/span&gt;
&lt;span class='s2'&gt;	 {ok, Apps} = application:get_key($(basename $@), applications), \&lt;/span&gt;
&lt;span class='s2'&gt;	 {ok, F} = file:open(&amp;quot;&lt;/span&gt;&lt;span class='nv'&gt;$@&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;, [write]), \&lt;/span&gt;
&lt;span class='s2'&gt;	 io:format(F, \&amp;quot;~p.~n\&amp;quot;, [{release, {\&amp;quot;$(basename $@)\&amp;quot;, \&amp;quot;$(SRCREV)\&amp;quot;}, \&lt;/span&gt;
&lt;span class='s2'&gt;	 {erts, erlang:system_info(version)}, \&lt;/span&gt;
&lt;span class='s2'&gt;	 lists:map(fun (App) -&amp;gt; application:load(App), \&lt;/span&gt;
&lt;span class='s2'&gt;	 {ok, Vsn} = application:get_key(App, vsn), \&lt;/span&gt;
&lt;span class='s2'&gt;         {App, Vsn} end, Apps ++ [$(basename $@)])}]), \&lt;/span&gt;
&lt;span class='s2'&gt;	 file:close(F), halt(0).&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You have to define &lt;code&gt;$(APP)&lt;/code&gt; to be the name of your application.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Using jQuery to display a Yahoo! Pipe</title>
    <link href="http://www.rigtorp.se/2010/03/14/yahoo-pipes-jquery.html"/>
    <updated>2010-03-14T00:00:00-05:00</updated>
    <id>http://www.rigtorp.se/2010/03/14/yahoo-pipes-jquery</id>
    <content type="html">&lt;h1 id='using_jquery_to_display_a_yahoo_pipe'&gt;Using jQuery to display a Yahoo! Pipe&lt;/h1&gt;

&lt;p&gt;I found myself wanting to display a feed on a webpage and it turned out to be a peace of cake using &lt;a href='http://pipes.yahoo.com/pipes/'&gt;Yahoo! Pipes&lt;/a&gt; and &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;script&lt;/span&gt; &lt;span class='nx'&gt;type&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class='nx'&gt;src&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;jquery.js&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class='err'&gt;/script&amp;gt;&lt;/span&gt;
&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;script&lt;/span&gt; &lt;span class='nx'&gt;type&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;ready&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getJSON&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;http://pipes.yahoo.com/pipes/pipe.run?_id=PIPEID&amp;amp;\&lt;/span&gt;
&lt;span class='s2'&gt;_render=json&amp;amp;_callback=?&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
      &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;each&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;value&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;items&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;item&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
          &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#items&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; 
	  &lt;span class='nx'&gt;item&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;link&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;item&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;title&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='err'&gt;/script&amp;gt;&lt;/span&gt;

&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;ul&lt;/span&gt; &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;items&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='err'&gt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Just replace &lt;code&gt;PIPEID&lt;/code&gt; with the id of your pipe.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Erlang Latency Guide</title>
    <link href="http://www.rigtorp.se/latency.html"/>
    <updated>2009-11-20T00:00:00-05:00</updated>
    <id>http://www.rigtorp.se/latency</id>
    <content type="html">&lt;h1&gt;Erlang Latency Guide&lt;/h1&gt;

&lt;h2 id=introduction&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Latency is a tricky subject, sometimes it's not even clear what or
how to measure it. I've had the experience of writing a fairly complex
system requiring low latencies in Erlang. Fortunately Erlang provides
really good baseline performance. Most of the time you simply write
your program and it will perform well. There are however a few tricks
that can be used to lower the latencies of a specific path in the
system. This document describes a few of these tricks.


&lt;h2 id=yield&gt;Yield&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://erlang.org&quot;&gt;Erlang&lt;/a&gt; allows you to design
efficient concurrent systems without caring how processes are
scheduled or how many cores the system is running on. When running
Erlang with multiple schedulers (generally one per CPU-core) the
runtime will balance the load between the schedulers by migrating
processes to starved schedulers. There is no way to bind processes to
schedulers or control how processes are migrated between
schedulers. This introduces a non-deterministic behavior in the
system and makes it hard to control latency.

&lt;p&gt;A common pattern is to have
a &lt;a href=&quot;http://en.wikipedia.org/wiki/Multiplexer&quot;&gt;
demultiplexer&lt;/a&gt; that receives a message, sends it to some other
process/processes and then performs some additional processing on the
message:

&lt;pre&gt;&lt;code&gt;
loop(State) -&gt;
    receive 
        Msg -&gt;
            Pid = lookup_pid(Msg, State),
	    Pid ! Msg,
	    State2 = update_state(Msg, State),
	    loop(State2)
    end.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After the message has been sent the receiving process will be ready
to execute, but unless the receiving process is on a different
scheduler the demultiplexer will first finish executing. Ideally we
would bind the demultiplexer to one scheduler and bind the receiving
processes to the other schedulers, but that's not allowed in Erlang.

&lt;p&gt;Erlang provides only one simple, but powerful way to control
scheduling: The &lt;a href=&quot;http://www.erlang.org/doc/man/erlang.html&quot;&gt;
built-in function
(BIF)&lt;/a&gt; 
&lt;a href=&quot;http://www.erlang.org/doc/man/erlang.html#erlang:yield-0&quot;&gt; 
&lt;code&gt;erlang:yield/0&lt;/code&gt;&lt;/a&gt; lets processes voluntarily give up
execution and let other processes get a chance to execute.

&lt;p&gt;The demultiplexer pattern can be modified by adding
&lt;code&gt;erlang:yield()&lt;/code&gt; after sending the message:

&lt;pre&gt;&lt;code&gt;
loop(State) -&gt;
    receive 
        Msg -&gt;
            Pid = lookup_pid(Msg, State),
	    Pid ! Msg,
            erlang:yield(),
	    State2 = update_state(Msg, State),
	    loop(State2)
    end.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After the message has been sent the demultiplexer will give up
execution. If the demultiplexer and the receiver are on the same
scheduler the receiver will execute before the demultiplexer finishes
executing, if they are on different schedulers they will execute in
parallel.

&lt;p&gt;Using the &lt;code&gt;erlang:yield/0&lt;/code&gt; BIF it's possible to control
the scheduling of Erlang processes. If used correctly this can reduce
the latency in a system.


&lt;h2 id=network&gt;Network&lt;/h2&gt;

&lt;p&gt;All network I/O in Erlang is implemented as
an &lt;a href=&quot;http://ftp.sunet.se/pub/lang/erlang/doc/man/erl_driver.html&quot;&gt;
Erlang driver&lt;/a&gt;. The driver is interfaced by the
module &lt;code&gt;prim_inet&lt;/code&gt; which in turn is interfaced by the
network related modules in
the &lt;a href=&quot;http://www.erlang.org/doc/apps/kernel/index.html&quot;&gt; kernel
application&lt;/a&gt;.

&lt;p&gt;There is a performance issue with the &lt;code&gt;prim_inet:send/2&lt;/code&gt;
and &lt;code&gt;prim_inet:recv/2&lt;/code&gt; functions affecting all the network
related modules. When calling &lt;code&gt;prim_inet:send/2&lt;/code&gt;
or &lt;code&gt;prim_inet:recv/2&lt;/code&gt; the process will do a selective
receive. If the process's message queue is long there will be a
performance penalty from doing this selective receive.

&lt;p&gt;For receiving there is a simple solution to this problem: use
the &lt;a href=&quot;http://www.erlang.org/doc/man/inet.html#setopts-2&quot;&gt;
&lt;code&gt;{active, once}&lt;/code&gt; socket option&lt;/a&gt;. 

&lt;p&gt;A simple selective receive-free TCP receiver:

&lt;pre&gt;&lt;code&gt;
loop(Sock) -&gt;
    inet:setopts(Sock, [{active, once}]),
    receive
        {tcp, Sock, Data} -&gt;
            loop(Sock);
        {tcp_error, Sock, Reason} -&gt;
            exit(Reason);
        {tcp_closed, Sock} -&gt;
            exit()
    end.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To implement sending without doing a selective receive it is
necessary to use the low-level port interface
function &lt;a href=&quot;http://www.erlang.org/doc/man/erlang.html#port_command-2&quot;&gt;&lt;code&gt;
erlang:port_command/2&lt;/code&gt;&lt;/a&gt;. Calling &lt;code&gt;erlang:port_command(Sock,
Data)&lt;/code&gt; on a TCP socket would send the data &lt;code&gt;Data&lt;/code&gt; on
the socket and return a reference &lt;code&gt;Ref&lt;/code&gt;. The socket will
reply by sending &lt;code&gt;{inet_reply, Ref, Status}&lt;/code&gt; to the process
that called &lt;code&gt;erlang:port_command&lt;/code&gt;.

&lt;p&gt;A simple selective receive-free TCP writer:

&lt;pre&gt;&lt;code&gt;
loop(Sock) -&gt;
    receive
        {inet_reply, _, ok} -&gt;
            loop(Sock);
        {inet_reply, _, Status} -&gt;
            exit(Status);
        Msg -&gt;
            try erlang:port_command(Sock, Msg)
            catch error:Error -&gt; exit(Error)
            end,
            loop(Sock)
    end.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Though not Erlang specific it is important to remember to tune the
send and receive buffer sizes. If the TCP receive window is full data
may be delayed up to one network round trip. For UDP, packets will be
dropped.


&lt;h2 id=distribution&gt;Distribution&lt;/h2&gt;

&lt;p&gt;Erlang allows you to send messages between processes at different
nodes on the same or different computers. It is also possible to
interact
with &lt;a href=&quot;http://www.erlang.org/doc/tutorial/overview.html#cnode&quot;&gt;
C-nodes&lt;/a&gt; (Erlang nodes implemented in C). The communication is done
over TCP/IP and obviously this introduces latencies, especially when
communicating between nodes on a network.

&lt;p&gt;Even when the nodes are running on the same computer they
communicate using TCP/IP over
the &lt;a href=&quot;http://en.wikipedia.org/wiki/Loopback&quot;&gt; loopback
interface&lt;/a&gt;. Different operating systems have widely different
loopback performance
(&lt;a href=&quot;http://en.wikipedia.org/wiki/Solaris_(operating_system)&quot;&gt;Solaris&lt;/a&gt;
has lower latency than &lt;a href=&quot;http://en.wikipedia.org/wiki/Linux&quot;&gt;
Linux&lt;/a&gt;). If your system uses the loopback interface it's a good
idea to consider this.


&lt;h2 id=reading&gt;Further Reading&lt;/h2&gt;

&lt;p&gt;
&lt;ul&gt;

&lt;li&gt;&lt;code&gt;erts/preloaded/src/prim_inet.erl&lt;/code&gt; from the Erlang
release

&lt;li&gt;&lt;code&gt;erts/emulator/drivers/common/inet_drv.c&lt;/code&gt; from the
Erlang release

&lt;/ul&gt;


</content>
  </entry>
  

</feed>

