<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5338845766123238061</id><updated>2025-01-16T02:44:49.972-08:00</updated><title type='text'>Antics with semantics</title><subtitle type='html'>Rants, cants, vaunts and taunts about programming and computers</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-948414200958838463</id><published>2019-07-23T10:31:00.002-07:00</published><updated>2019-07-24T14:28:44.427-07:00</updated><title type='text'>Making a scene with JS - Dwitter Intro</title><content type='html'>I&#39;m back after a hiatus of many years - I recently came across dwitter.com which is a website where you make graphical demos with 140 bytes javascript&lt;br /&gt;
&lt;br /&gt;
I really got hooked onto it, because it takes me back 30 years when I spent many hours on a BBC micro trying to get weird patterns drawn on the screen using SIN, COS etc.&lt;br /&gt;
&lt;br /&gt;
For many of us, the entry into programming was because you could get the computer to draw stuff.&lt;br /&gt;
In a way this is one of the most purest and creative forms of programming - you have a fixed arena and you need to use it - no quarter given.&lt;br /&gt;
&lt;br /&gt;
140 bytes seems very little, but believe me, a lot is possible - some of the demos there are unbelievably complex.&lt;br /&gt;
&lt;br /&gt;
I made several in the past few days, and I&#39;ve started picking up some of the tricks&lt;br /&gt;
I&#39;m going to be writing a series of blog posts about each dweet along with the tips and tricks I&#39;m discovering for this code-golf as an amateur&lt;br /&gt;
&lt;br /&gt;
So without further ado - let&#39;s look at dweet framework provided:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/47c2fa5befe41fa7f85a0d43fc34a6bc.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
It&#39;s simple enough - As you make more dweets you start cursing why the canvas method names are so long! But we work with what we have.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the first dweet I made - Rain-bough-nut&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;false&quot; frameborder=&quot;0&quot; height=&quot;500&quot; src=&quot;https://www.dwitter.net/e/15080&quot; width=&quot;800&quot;&gt;&lt;/iframe&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For development I made my own HTML file based on the dweet github code - it works just like the original, except I added code to start and stop the timer on click - this is useful when debugging.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/5167f06c42a6ed887742a37c2e3c2276.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
I write my code in a file called demo.js in normal style and then once it&#39;s working, I try my best to cut it down to 140 bytes - it&#39;s not always possible!&lt;br /&gt;
&lt;br /&gt;
Let&#39;s look at how this multi-colored doughnut is rendered&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/1f828561d708c3cb04aa5fe14c66537f.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
There are two kinds of dweets - those that redraw the whole canvas every frame and those that keep drawing on the earlier frames content - this dweet is the latter kind.&lt;br /&gt;
&lt;br /&gt;
The basic shape is created by drawing rectangles in an inward spiral with this&lt;br /&gt;
&lt;br /&gt;
&lt;code style=&quot;color: yellow;&quot;&gt;x.fillRect(780+r*S(b),420+r*C(b),80,90)&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The 780 and 420 are approximately the center offset by the size of one rectangle - the center of the canvas is 960,540 and the rectangles are 80,90 in size - hence the spiral will be centered if draw rectangles all around at &lt;code style=&quot;color: yellow;&quot;&gt;960-80 = 880&lt;/code&gt; and &lt;code style=&quot;color: yellow;&quot;&gt;540-90 = 450&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This code has &lt;code style=&quot;color: yellow;&quot;&gt;780,420&lt;/code&gt; left over from some experimentation and is does not center perfectly - too late to change now!&lt;br /&gt;
&lt;br /&gt;
&lt;code style=&quot;color: yellow;&quot;&gt;r * S(b)&lt;/code&gt; and &lt;code style=&quot;color: yellow;&quot;&gt;r * C(b)&lt;/code&gt; obviously makes a circular path. Here we are reducing the radius from about &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;382&lt;/span&gt;&lt;/b&gt; to &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;255&lt;/span&gt;&lt;/b&gt; over the course of about &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;4.5 radians&lt;/span&gt;&lt;/b&gt;, turning the circular path into a mild spiral.&lt;br /&gt;
On each frame, the angle &lt;b&gt;b&lt;/b&gt; is incremented at the rate of &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;1 radian&lt;/span&gt;&lt;/b&gt; per second.&lt;br /&gt;
&lt;br /&gt;
The only remaining trick is the coloring - canvas supports alpha blending, so we can take full advantage of this.&lt;br /&gt;
&lt;code style=&quot;color: yellow;&quot;&gt;&lt;br /&gt;
sa=S(t)*z&lt;br /&gt;
x.fillStyle=R(z-sa,z-C(t)*z,sa,0.01)&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Once again in my haste when making this, I completely ignored the fact that I was using RGB levels outside the valid range &lt;span style=&quot;color: yellow;&quot;&gt;&lt;b&gt;0&lt;/b&gt; to &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;255&lt;/span&gt;&lt;/b&gt;.&lt;br /&gt;
In this code R ends up cycling from &lt;span style=&quot;color: yellow;&quot;&gt;&lt;b&gt;0&lt;/b&gt; to &lt;b&gt;512&lt;/b&gt;&lt;/span&gt;, G from&lt;span style=&quot;color: yellow;&quot;&gt; &lt;b&gt;0&lt;/b&gt; to &lt;b&gt;512&lt;/b&gt;&lt;/span&gt; (90 degrees out of phase with R) and B from &lt;span style=&quot;color: yellow;&quot;&gt;&lt;b&gt;0&lt;/b&gt; to &lt;b&gt;255&lt;/b&gt; to &lt;b&gt;0&lt;/b&gt; to &lt;b&gt;255&lt;/b&gt;&lt;/span&gt;&amp;nbsp;and back. A complete cycle takes &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;2*PI radians&lt;/span&gt;&lt;/b&gt;, and since we use the time variable as the angle, its about &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;6.28 seconds&lt;/span&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
The alpha channel is set to &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;0.01&lt;/span&gt;&lt;/b&gt; which is the lowest possible value - so each rectangle drawn merely tints the one below.&lt;br /&gt;
As the R G and B cycle out of phase, we end up getting all the hues and the semi-transparent rectangles overlapping create a fairly tasty looking doughnut effect.&lt;br /&gt;
&lt;br /&gt;
I didn&#39;t really use any minification tricks in this code, except reusing the value &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;255&lt;/span&gt;&lt;/b&gt; as much as possible. Every constant we define uses up valuable bytes, so making one of them do duty in many places is useful.&lt;br /&gt;
&lt;br /&gt;
As I wrote more dweets, I learned a few more tricks of the trade - in future posts I will describe them&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/948414200958838463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2019/07/making-scene-with-js-dwitter-intro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/948414200958838463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/948414200958838463'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2019/07/making-scene-with-js-dwitter-intro.html' title='Making a scene with JS - Dwitter Intro'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-3637393383299029728</id><published>2016-05-17T14:14:00.001-07:00</published><updated>2016-05-17T14:36:40.321-07:00</updated><title type='text'>Topcoder problem analysis - ChessCover (Inv 2001 Semi A+B 1000 pointer)</title><content type='html'>&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Problem statement&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=202&amp;amp;rd=53&quot;&gt;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=202&amp;amp;rd=53&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This turned out simpler than the 500 pointer, especially since I had the 2d iterator class. Piece of cake - didn&#39;t take more than 30 minutes to code.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;
&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Solution&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/f2fec946601114474835cee98e18761c.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The algorithm is really simple - &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We scan the chess board for pieces&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;For each piece except knights and pawns we call &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;attack()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;, passing an array of directions&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;For knights and pawns we call &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;attackOne()&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;The &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;attack()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; function iterates in each of the passed directions starting at that piece and marks the empty squares unsafe. It stops if any piece is encountered&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;The &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;attackOne()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; function does the same, but only one step instead of all the way&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The fact that we had an iterator means, we don&#39;t have to care about the bounds of the board, or do anything differently for any direction.&lt;/div&gt;
&lt;div&gt;
Note the use of &lt;span style=&quot;color: orange;&quot;&gt;std::initializer_list&lt;/span&gt; to allow us to pass literal array constants to a function and treat them as a container (with zero runtime overhead)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This was one of the most satisfying bits of code I wrote so far in this series.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/3637393383299029728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-chesscover.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3637393383299029728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3637393383299029728'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-chesscover.html' title='Topcoder problem analysis - ChessCover (Inv 2001 Semi A+B 1000 pointer)'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-3606961246366929063</id><published>2016-05-17T13:56:00.000-07:00</published><updated>2016-05-17T13:56:25.682-07:00</updated><title type='text'>Topcoder problem analysis - Tothello (Inv 2001 Semi A+B 500 pointer)</title><content type='html'>&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Problem statement&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=203&amp;amp;rd=53&quot;&gt;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=203&amp;amp;rd=53&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This is quite straightforward - you have to scan every row, column and diagonal range on the board and detect if you can surround a contiguous line of your opponent&#39;s pieces on both sides by placing your next piece and capture them. Each set of captured pieces becomes your piece and they can cause further cascading captures until there are no more capture situations on the board&lt;br /&gt;
&lt;br /&gt;
You have to find the move that captures the maximum number of pieces. &lt;br /&gt;
&lt;br /&gt;
The obvious way to do it (as many solutions do) is to scan the board using for() loops - To me this seemed a terribly ugly way of doing this.&lt;br /&gt;
&lt;br /&gt;
We&#39;re trying to find a pattern like RBBBBBBR along any straight line of the board. If it were only in the horizontal direction we can do this cleanly with just two calls to adjacent_find().&lt;br /&gt;
However we need to handle eight different directions not just the horizontal ones.&lt;br /&gt;
&lt;br /&gt;
So I decided that a 2d iterator would be interesting to write.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;2D iterator&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Usually, iterators are a subtype of a container, but here we&#39;re not going to do that, since we can&#39;t extend vector and so on.&lt;br /&gt;
Instead we create a class that holds a reference/pointer to its container - in our case a &lt;span style=&quot;color: orange;&quot;&gt;vector&amp;lt;vector&amp;lt;T&amp;gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
STL iterators have a lot of properties and are written in a consistent way, since they all work on linear one dimensional sequences. They move in two directions at most.&lt;br /&gt;
&lt;br /&gt;
Our requirements are different:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We want the iterator to be able to move in any of the eight directions&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We want to have the bare minimum of operations implemented and a couple of extras&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The basic operations we need:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Ability to set a direction&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Copy constructible&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: yellow;&quot;&gt;*, &amp;gt;, ==, !=&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; and pre-increment operators (post increment is not useful enough)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Extras:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;&lt;span style=&quot;color: orange;&quot;&gt;bool&lt;/span&gt; operator to check if an iterator is not at the end.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;A function to get a successor to an iterator without mutating it.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;a &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;distance()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; function - I could not get &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;std::distance()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; to work right with my iterator. Needs some studying&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Full implementation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The code is not brilliant and some corners are cut, but it does the job.&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/2336b60345408ec6dde389a945c87666.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Some points to note:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Coordinates and increments are simple &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;pair&amp;lt;int, int&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We predefine the eight directions&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We have to store a pointer to the container we refer to, so we can refer to its contents.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;The increment operator clamps to the first out of bounds co-ordinate&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Whatever extra boilerplate the STL needs is borrowed from &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;std::vector&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Our end&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;iterator is created from another iterator, not from the container as is usually done, since our iterator has a direction&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The way its used is - you construct an iterator passing in a vector of vectors, a coordinate, and a direction. You construct an end of range iterator in turn from that. Now you can treat the two iterators like any other ones you have seen.&lt;br /&gt;
&lt;br /&gt;
Once we have this 2d iterator class, the original problem becomes almost trivial to solve&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Full implementation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/69ffd9b244c1edc6864576941078aba9.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The algorithm is as follows:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We place a piece tentatively on the board on an empty position&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We look for any captures - on every column, on every row, every primary and secondary diagonal&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;If anything was captured, repeat the above step because we may have cascading captures&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;If we had no captures, count how many total pieces we have after&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Repeat this entire process for every empty position on the board and see what is the maximum count we can get.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;The main work is done in apply() and &lt;span style=&quot;color: yellow;&quot;&gt;applyOne()&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: yellow;&quot;&gt;apply()&lt;/span&gt; calls &lt;span style=&quot;color: yellow;&quot;&gt;applyOne()&lt;/span&gt; eight times, each time passing a co-ordinate and two directions - The two directions are the primary and secondary axis to scan - For example we&#39;d scan each column by starting at each point on the first row and going downwards.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: yellow;&quot;&gt;applyOne()&lt;/span&gt; is extremely simple since we can use the STL&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;We need to find a pattern like &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;100000001 &lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;on the board along the secondary axis starting at each point on the primary axis (our representation uses 1 for our piece and 0 for the opponents)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Call adjacent_find to see if there is a &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;1,0&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Call adjacent_find on that result to find an &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;0,1&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;&amp;nbsp;- the fun part is that if the previous call had not succeeded, it would have returned the &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;end()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; iterator, so this call will do nothing. We don&#39;t have to do any messy and error prone special casing.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Now we have two iterators one that points to an &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;1,0&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;&amp;nbsp;and another to a &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;0,1&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;If both are valid, we count how many &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;0s&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; exist between the two surrounding &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;1s&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;If that count is equal to the distance between the two iterators, everything between the &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;1s&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;&amp;nbsp;was a &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;&amp;nbsp;and thus we have a capture&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;If we have a capture, just fill that captured range with &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;1&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;It looks like a lot of work to write an iterator just for this problem, but we made our code simple and error free - just imagine the nightmare of writing several loops, each which has multiple conditions. Maybe some people are so smart they can juggle all that in their head. Personally, I&#39;d let the compiler handle it.&lt;br /&gt;
Some of the solutions in the practice room are horrendously verbose. A typo would be fatal for such code.&lt;br /&gt;
&lt;br /&gt;
It turns out that the 1000 point problem in this room is a similar problem involving a 2d game board. Having this iterator code made that problem trivial to solve - in fact it turned out even simpler than this one!&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;Use the abstraction Luke!&lt;/span&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/3606961246366929063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-tothello-inv.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3606961246366929063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3606961246366929063'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-tothello-inv.html' title='Topcoder problem analysis - Tothello (Inv 2001 Semi A+B 500 pointer)'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-7542128109323675076</id><published>2016-05-16T15:33:00.001-07:00</published><updated>2016-05-17T03:52:39.155-07:00</updated><title type='text'>Topcoder problem analysis - RuleEngine (CC 2002 REG Semi 1000 pointer)</title><content type='html'>&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Problem statement&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=352&amp;amp;rd=62&lt;br /&gt;
&lt;br /&gt;
I have no idea why this was chosen as a 1000 pointer - the problem is really simple looking. So simple in fact that many coders missed a couple of obvious details, and I spent a while successfully challenging several solutions in the practice room... &lt;br /&gt;
&lt;br /&gt;
The cardinal mistakes people made:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Forget to use a 64 bit integer for computations - 19 to the 14th power is a huge number.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: orange;&quot;&gt; Someone actually implemented a simple &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;BigInteger&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; class in C++, without realizing they could use a &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;long long&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Write a nested for loop that checked all possible numbers for each rule! Probably not going to terminate in the lifetime of the universe!&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Another thing I noticed is the repetitivity of the code in many solutions. If you have two blocks of code that differ in only a few places, it begs to be converted into a function, or often a macro.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Solution&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The correct way to solve the problem is:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Go through each rule, and count how many numbers fulfill that rule&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Multiply all the above counts together&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/b33ddc55bd0f29bd329c4df598f48b42.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Note the usage of the &lt;span style=&quot;color: yellow;&quot;&gt;HANDLE_OP()&lt;/span&gt; macro to handle repetitive code - Macros allow you to de-duplicate code in ways that you just cannot by any other means. Here we used the fact that the literal symbol &quot;!=&quot; and so on is the actual C++ operator for that rule. Had we used anything but a macro, we&#39;d have had to write a tedious case statement or similar logic, mapping strings to relational operators.&lt;br /&gt;
&lt;br /&gt;
Note the appending of &lt;span style=&quot;color: yellow;&quot;&gt;&quot;,0&quot;&lt;/span&gt; to the rules, to make sure the parsing of all rules is uniform. You can ensure that a condition is always met in order to eliminate a conditional statement - this is similar in principle to &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: orange;&quot;&gt;sentinels&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;, a much underrated tool in your programming toolbox. </content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/7542128109323675076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-ruleengine-cc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7542128109323675076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7542128109323675076'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-ruleengine-cc.html' title='Topcoder problem analysis - RuleEngine (CC 2002 REG Semi 1000 pointer)'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-4744028268299967079</id><published>2016-05-16T14:35:00.000-07:00</published><updated>2016-05-17T03:52:53.212-07:00</updated><title type='text'>Topcoder problem analysis - Birds (CC 2002 REG Semi 500 pointer)</title><content type='html'>&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Problem statement&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=330&amp;amp;rd=62&quot;&gt;https://community.topcoder.com/stat?c=problem_statement&amp;amp;pm=330&amp;amp;rd=62&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This is not a very hard problem once you figure out the right algorithm. I spent a lot of time chasing a solution after having misread the problem.&lt;br /&gt;
I assumed that a bird is migratory if it spends its time in two regions for 90 days or more each in &lt;b&gt;&lt;i&gt;any&lt;/i&gt;&lt;/b&gt; 365 day period, rather than just the specified start date to December 31st.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: orange;&quot;&gt;Lesson #1 : &lt;/span&gt;Read the problem statement carefully!&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Subtask - Find the number of days between two dates in a year&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The naive way to do this is to calculate it by summing up the months upto the current and adding the date.&lt;br /&gt;
Instead of doing this in a loop every time, we can precalculate this with &lt;span style=&quot;color: orange;&quot;&gt;partial_sum()&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/7a78a0cacf9823d27ad4c14c1dd2dfb9.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;The algorithm itself&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
My solution was as follows:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Put the locations in an array and sort by date.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Find all pairs of locations the bird stays which are at least 1000 KM distant&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;For every pair of locations say A and B, walk the array starting from A;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Keep walking the array as long as every location is within 1000 KM of A and more than 1000 KM from B. Sum up the time spent along this sequence.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;The entries that were walked are all in the same region and we have the total time spent in that region.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Repeat the same process vice versa starting from B&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Now we have the total time spent in both the regions, if both are &amp;gt; 90 days were have a migration!&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The third step finds the longest time spent in any one region - there is a lot of redundant computation - For e.g. if we have ABCDEFG as locations, and G happens to be 1000 Km away from the rest, while all the others are close to each other, we will be walking from A to G, B to G, C to G and so on - but we don&#39;t care, since all that matters is that the time spent in some subset of [A to F] is 90 days and the stay in G itself is 90 days.&lt;br /&gt;
&lt;br /&gt;
There is only one tricky detail - time spent at any location is given by &lt;span style=&quot;color: orange;&quot;&gt;t[d + 1] - t[d]&lt;/span&gt; - but obviously the last element of the locations array doesn&#39;t have a successor.&lt;br /&gt;
It&#39;s implicitly assumed that if a bird no longer moves, it stays where it was until December 31st.&lt;br /&gt;
So we put in a January 1st (next year or day 366) sentinel at the end of the locations array, so we have a way for the loop to be within bounds.&lt;br /&gt;
&lt;br /&gt;
Perversely, the problem statement explicitly says the same is not the case for the beginning of the year - in other words, if a bird migrated on March 1st, you don&#39;t assume it lived at that location before that. I assumed the opposite the first time I read the problem and didn&#39;t figure it out until one system test case failed! &lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Final code&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/92b19ed0cd87768a2c4546017a19c983.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
The code seems quite verbose, but the essence of the algorithm is only about 10 lines.&lt;br /&gt;
Note the simplicity of using &lt;span style=&quot;color: orange;&quot;&gt;FOR_EVERY_UNIQUE_PAIR()&lt;/span&gt;&lt;br /&gt;
Also notice the use of &lt;span style=&quot;color: orange;&quot;&gt;stoi()&lt;/span&gt; - C++11 onwards has string to numeric conversion functions and vice versa. The only alternative before that was istringstream or -- Dog forbid! --  the &lt;span style=&quot;color: orange;&quot;&gt;sprintf()&lt;/span&gt; family </content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/4744028268299967079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-birds-cc-2002.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4744028268299967079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4744028268299967079'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-birds-cc-2002.html' title='Topcoder problem analysis - Birds (CC 2002 REG Semi 500 pointer)'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-4120602729715939067</id><published>2016-05-16T13:19:00.000-07:00</published><updated>2016-05-17T14:30:40.660-07:00</updated><title type='text'>C++ as it is meant to be used</title><content type='html'>&lt;br /&gt;
There are two things that are the biggest blessing as well as the biggest curse for C++&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;A) It is (almost perfectly) backward compatible with C&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps nothing else ensured its success, but it also means that people tend to clump together the two as C/C++ and for most C++ is learned after prior exposure to C. This only leads to folks using C++ as a better C, bringing in all the bad habits :&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Globals&lt;/span&gt; &lt;span style=&quot;color: orange;&quot;&gt;- In C it&#39;s impossible to avoid them, but they can and should be avoided in C++ ( Why? )&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Manual memory management&lt;/span&gt; &lt;span style=&quot;color: orange;&quot;&gt;- For every flower there&#39;s a bee, For every fruit there&#39;s a tree, but unfortunately for every &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;malloc()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; there&#39;s not always a &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;free()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;. The paranoia of the bugs caused by this led the designers of Java to opt for garbage collection instead (Of course they forgot that memory is not the only resource that needs to be managed!!). In C++ we have tools for the job - Deterministic finalization means we can use RAII classes or simply use auto pointers to ensure matched allocation and deallocation. In fact, most of the time, you can simply use a &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;std::string&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; as a buffer. Google does it in their protocol buffer code - If it&#39;s good enough for google it&#39;s good enough for me. In the past few years I can&#39;t recall having used new or delete[] for buffers (or even for objects for that matter)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Using the C functions&lt;/span&gt; - &lt;span style=&quot;color: orange;&quot;&gt;using &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;strcpy()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;printf()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;scanf()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;, and their brethren is a surefire way to induce vulnerabilities and bugs. C++ gives you a nice string, stream I/O and if you use boost, you can use type safe code like the lexical_cast and the format library.&lt;br /&gt;
It is this C legacy which leads to insecure and fragile code.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: yellow;&quot;&gt;&lt;b&gt;B) It is labeled &quot;Object Oriented&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Destructors, Encapsulation, Operator overloading and Pure abstract classes are quite useful features - Especially destructors, without with &lt;b&gt;RAII&lt;/b&gt; would be impossible.&lt;br /&gt;
&lt;br /&gt;
However, I&#39;m not much of a fan of the OO bandwagon. OO has it&#39;s conveniences and good points, but in emphasizing it above all else, there is too much hype. It really does not give you much of a new way of looking at problem solving unless you opt for pure message passing style OO like &lt;i&gt;&lt;b&gt;Smalltalk&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
Most of day to day OO usage could be very well done in C - Think of the stdio.h functions or most of the Win32 API that take an opaque FILE* or HANDLE respectively. I tend to agree with this gentleman&#39;s opinion on the matter.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;What does good C++ look like?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In my opinion, minimum reliance on code that you have written, and maximum use of well written libraries ( I refer to the STL and boost ). Even if it makes the code only readable by someone more experienced - No one said C++ is an easy language.&lt;br /&gt;
&lt;br /&gt;
Some rules of thumb that I tend to follow&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Use containers instead of C arrays&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Use string rather than &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;char*&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; buffers&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Avoid new and &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;malloc()&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Avoid explicit loops over data when possible, use &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;copy()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: yellow;&quot;&gt;transform()&lt;/span&gt;&lt;span style=&quot;color: orange;&quot;&gt; etc.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Avoid pointers as much as possible&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Avoid functions that take varargs ... arguments&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: orange;&quot;&gt;Once again - do not reinvent the wheel, unless you need a square one, it&#39;s been done before, there&#39;s always a well written library out there with the functionality you need.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/4120602729715939067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/c-as-it-is-meant-to-be-used.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4120602729715939067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4120602729715939067'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/c-as-it-is-meant-to-be-used.html' title='C++ as it is meant to be used'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-8965973752806641272</id><published>2016-05-16T13:01:00.002-07:00</published><updated>2016-05-17T14:27:39.263-07:00</updated><title type='text'>Topcoder problems - Tokenizing</title><content type='html'>One of the most common tasks in topcoder problems is tokenizing a string into individual elements. Almost always the entries are separated by spaces.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;The naive and obvious version&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Seen surprisingly often in various avatars, it is a C mode of thinking goes something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/a2573df2b8328c6323a5dc025c6da207.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Very verbose and tedious!&lt;br /&gt;
Of course on topcoder they usually write tersely equivalent code on a single line #defined as a macro or an inline function.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Can we do better?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a more C++ like version&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/94f82cdfa83cdf03fdbd2c0f059550e2.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Still smells like C&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;How about&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Think in functional terms, get the loop mentality out of the way - The STL is your friend :&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/85145ec2364d13cd9794080457d44938.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Nice and neat!&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Can this be a one-liner?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Let&#39;s try putting everything together...&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/57a4bd2915e28d94facdb02b964dc6ba.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Unfortunately this is not correct. The temporary istringstream dies after the istream iterator is constructed, so bad things will happen. The constructor of the istream_iterator takes a istream&amp;amp; rather than a const istream&amp;amp; otherwise it would be workable - See &lt;a href=&quot;https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/&quot;&gt;this&lt;/a&gt;&lt;br /&gt;
Actually should have been obvious... &lt;br /&gt;
You cannot read stuff out of a const reference to a stream since it changes state when you do.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;What about other delimiters?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
C++ streams are tied to locales, so they read stuff based on the definition of isspace() for the current locale. There seems to be no way to manufacture our own locales for splitting strings on things other than whitespace, so we need a different approach:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/53427e6ed83925f656a949f802e145cf.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Neat huh?&lt;br /&gt;
If that looks like Greek and Latin to you, don&#39;t worry, it looks that way to me too, three days after writing it.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: orange;&quot;&gt;Let&#39;s analyze what the heck is going on here...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The intent is as follows - we want to maintain two pointers/iterators - one points to the start of a word, and the other points to a separator (or end of string)&lt;br /&gt;
&lt;br /&gt;
The for loop starts by initializing ps(pointer to start), pe(pointer to end-of-string).&lt;br /&gt;
Since we use &lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;auto&lt;/span&gt;&lt;/b&gt; we have to assign something to pd(pointer to delimiter), so might as well assign ps to it. We are going to loop until ps reaches pe.&lt;br /&gt;
&lt;br /&gt;
Next we place the next available token into the result vector - &lt;span style=&quot;color: yellow;&quot;&gt;emplace_back()&lt;/span&gt; is a function that can push an element onto a vector without copying the value passed into it - it uses move semantics to achieve this. Whenever you push a temporary object onto a vector, use &lt;span style=&quot;color: yellow;&quot;&gt;emplace_back()&lt;/span&gt;&lt;br /&gt;
Remember never to reuse the emplaced object again, or else...&lt;br /&gt;
&lt;br /&gt;
OK, but what the hell is &quot;the next available token&quot; mentioned above?&lt;br /&gt;
It is a string consisting of an iterator range - the start of the range is obviously ps. The end of the range is the next delimiter in the string, or the end of the string if no such delimiter exists.&lt;br /&gt;
Well that&#39;s exactly what &lt;span style=&quot;color: yellow;&quot;&gt;find_first_of()&lt;/span&gt; does - returns an iterator in a range that has any one of the values you give it (here the characters in the string seps). If not found, it returns the end of the range, which is what we want.&lt;br /&gt;
&lt;br /&gt;
So all we need to do is set ps to the point after the delimiter, so we can grab the next token - this is done in the increment part of the for loop. If it goes past the end, were done. Assigning pd on the fly inside the expression is a neat way to avoid one extra line of code. Remember that everything in C/C++ except control statements return a value (In fact and BTW, in GNU C, there is an extension that lets every statement be a value).&lt;br /&gt;
&lt;br /&gt;
Not too bad at all! I can&#39;t think of a more neat version than this. I have some vague idea about using &lt;span style=&quot;color: yellow;&quot;&gt;adjacent_find()&lt;/span&gt;, &lt;span style=&quot;color: yellow;&quot;&gt;any_of()&lt;/span&gt; and so on, but I suspect it won&#39;t be as neat as this.&lt;br /&gt;
&lt;br /&gt;
One thing you might notice is that I use pointers instead of iterators. The point is that pointers are the best kind of iterator, and if you know that the underlying object is contiguous, one might as well use a pointer than an iterator (the compiler will actually generate almost the same code for an iterator in this case). There is nothing evil about pointers, as long as you use them sparingly in a type safe way.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s how it looks in the brief form using the macros from my topcoder template:&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/d5befa9c9caa399ac2d296b06cd76bae.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Try writing a similar split in your favorite language for kicks!</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/8965973752806641272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problems-tokenizing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/8965973752806641272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/8965973752806641272'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problems-tokenizing.html' title='Topcoder problems - Tokenizing'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-7547952967514964699</id><published>2016-05-16T11:32:00.001-07:00</published><updated>2016-05-17T03:53:14.345-07:00</updated><title type='text'>Topcoder problem analysis - A new hope</title><content type='html'>&lt;h4&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Intro&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;Off late, I&#39;ve started practising topcoder problems to get better at problem solving. I&#39;m in no state to compete in SRMs right now, but I&#39;ll try to practice as often as possible, till I feel up to it.&lt;br /&gt;
I&#39;d never ever solved a 1000 pointer before, in any amount of time. But I managed to solve a couple, albeit taking a lot of time.&lt;br /&gt;
My intent was not to just get code to work, but write good idiomatic C++, with some amount of terseness.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;h4&gt;&lt;b&gt;&lt;span style=&quot;color: yellow;&quot;&gt;Setup&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;The first thing I noticed is that the topcoder beta arena based on HTML really sucks. It doesn&#39;t let you browse problems by SRM and as far as I could tell, there is no way to see other peoples solutions. The good old Java applet still works, and I guess it will continue to work because it remains in production, so thank goodness for that. &lt;br /&gt;
&lt;br /&gt;
The first thing to do is to configure a good editor plugin - I used to use FileEdit and TZTester before, but Greed seems like the best thing to use right now. It also downloads the problem descriptions and is highly configurable. So far I haven&#39;t been able to get it to generate automated test code, but that&#39;s probably because the problems I opened are from very early matches, where the test cases are not specified in a standard form which the plugin can parse.&lt;br /&gt;
&lt;br /&gt;
The next thing is what template to use - as usual, a bunch of macros.&lt;br /&gt;
This is what I have right now: &lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/rep-movsd/9a5c966bb622a8203652345964853b63.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
Just a bunch of macros borrowed from many topcoder contestants. &lt;b&gt;all() &lt;/b&gt;is probably the most useful, followed by &lt;b&gt;FOR()&lt;/b&gt;, and &lt;b&gt;P()&lt;/b&gt; is invaluable while debugging. Most of them just reduce verbosity and avoid typos. One has to be careful to use macro names that are not identifiers, otherwise you can get some horrendous errors.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;&lt;h4&gt;&lt;b style=&quot;color: yellow; font-family: inherit;&quot;&gt;Modus operandi&lt;/b&gt;&lt;/h4&gt;My goal is not to try to write code as fast as possible. It is to try to write the best (by my taste) C++ for each problem. This means that I will try my best to refine a solution once I get it to work, or try to write it in a refined STL centric manner from the get go.&lt;br /&gt;
&lt;br /&gt;
In future posts I will try to dissect each problem, algorithmically and code wise, and try to show how best to leverage C++.&lt;br /&gt;
&lt;br /&gt;
Ideally I would like to see myself writing code in the very first iteration, that looks like the last iteration I produce now, after much refinement.&lt;br /&gt;
&lt;br /&gt;
In a contest situation, some of the code I write is not ideal, since in a contest, cleanliness of code is irrelevant, as is code duplication. If anything some contestants write code in a purposely obscure manner to thwart others from grokking the code.&lt;br /&gt;
&lt;br /&gt;
For practice purposes, I&#39;d rather write elegant code. Some terseness and one-lining is nice though as code golf.&lt;br /&gt;
I do not adhere strictly to my variable naming convention, since it leads to come verbosity. I also break some whitespace rules to make the code look compact.&lt;br /&gt;
A supplementary library of code is getting accumulated as I do these problems, since some things are patterns that repeat. &lt;br /&gt;
I will discuss those bits of code in future posts.&lt;br /&gt;
&lt;br /&gt;
&lt;hr style=&quot;border-color: #ff9900;&quot; /&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/7547952967514964699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-new-hope.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7547952967514964699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7547952967514964699'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2016/05/topcoder-problem-analysis-new-hope.html' title='Topcoder problem analysis - A new hope'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-3159997396096348683</id><published>2014-07-05T06:06:00.000-07:00</published><updated>2014-07-06T01:30:08.055-07:00</updated><title type='text'>A DOM of many hovered class</title><content type='html'>&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
.post-body { line-height:1.25;}
pc { color: #00FF00; font-style: italic; }
pf { color: #00FF00; }
pi { color: #FF8000; }
pn { color: #00FF00; }
pk { color: #FFFF00; font-weight: bold; }
ps { color: #FF8000; }
txo { color: orange;}
txy { color: yellow;}
.code { font-size: small; border-style:solid; border-width:1px; padding:0px; margin:0px; }
.serif {font-family: serif; font-size: small;}
.li { color: orange; margin: 0px; padding: 0px; line-height:1.25;}
.ul {font-family: serif; font-size: large;}
pre { padding:0px; margin:8px;}
.headin { color: yellow; font-size: large; font-family: Arial,Helvetica,sans-serif;}
hr { display: block; height: 1px;
    border: 0; border-top: 1px solid orange;
    margin: 1em 0; padding: 0; }
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;div class=&quot;serif&quot;&gt;So last week has been entriely about optimization. The website I&#39;m working on had serious performance issues and it needed to be fast, to qualify as working.&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;The problem&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The problem is simple - we have a back end database that supplies data about cloud computing jobs, and we need to display these in a table, allowing the user to view and control the jobs.&lt;br /&gt;
The data is refreshed every 30 seconds and each job element has about nine pieces of information. Four of them are shown in a table row, and the rest appear in an expandable row when the main row is clicked.&lt;br /&gt;
&lt;br /&gt;
The initial implementation had the server generate the whole HTML, and we simply fetched that via AJAX and assiged it using &lt;pk&gt;innerHTML&lt;/pk&gt; &lt;br /&gt;
This was unacceptable - despite gzip encoding, the amount of data per request is huge - For my test case, with ~900 jobs, the compacted HTML is about &lt;pk&gt;900 KB&lt;/pk&gt;, which gzips to ablut &lt;pk&gt;40 KB&lt;/pk&gt;. Each table row has a total of &lt;pk&gt;32&lt;/pk&gt; HTML tags, so we have about &lt;pk&gt;30000&lt;/pk&gt; styled HTML elements.&lt;br /&gt;
&lt;br /&gt;
This may not seem like much - you can easily generate and manipulate millions of rows in a HTML table, however, when you have nested tags, CSS, attributes, and event handlers, it starts to bog down.&lt;br /&gt;
&lt;br /&gt;
With Chrome, the &lt;pk&gt;innerHTML&lt;/pk&gt; approach was passable, but with IE 11 it was simply too much for the browser to handle. A factor of &lt;pk&gt;6x&lt;/pk&gt; to &lt;pk&gt;8x&lt;/pk&gt; slower.&lt;br /&gt;
Any action by the user that affects the jobs, causes a refresh, which made for a very laggy UI.&lt;br /&gt;
&lt;br /&gt;
Moreover the Django backend also spent too much time generating the HTML - Upto &lt;pk&gt;0.6&lt;/pk&gt; seconds just for this. Inconceivable!&lt;br /&gt;
&lt;br /&gt;
The table rows needed to have filtering - only certain rows would be visible, based on the selected tab in a tab control. The user needed to be able to select any number of jobs to perform job actions on them. Both selection and tab switching were too slow.&lt;br /&gt;
&lt;br /&gt;
Something had to be done! After much profiling and reading numerous blogs about javascript performance, I managed to speed up various things, by a factor of anywhere from 2x to 100x&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Lesson 1 - Templating on client side&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The first approach was to scrap the generation of HTML serverside, and send the job data as JSON to the client, to be rendered there instead.&lt;br /&gt;
&lt;br /&gt;
Now the JS would render the HTML for each job, using a very basic templating function. Using &lt;pk&gt;innerHTML&lt;/pk&gt; to construct the table was still inevitable. &lt;br /&gt;
&lt;br /&gt;
The server side time was reduced, and the simple javascript templater I wrote seemed so much faster, with negligible times to subtitute values into the HTML template. It was a simple search and replace function :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;function&lt;/pk&gt; template&lt;pk&gt;(&lt;/pk&gt;dict, str&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    &lt;pk&gt;for(&lt;/pk&gt;key in dict&lt;pk&gt;)&lt;/pk&gt;
       str.replaceAll&lt;pk&gt;(&lt;/pk&gt;&#39;&amp;lt;&amp;lt;&#39; + key + &#39;&amp;gt;&amp;gt;&#39;, dict[key]&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The reason for Django&#39;s slowness seems to be that its template engine is not so much a glorified &lt;pk&gt;printf&lt;/pk&gt; but quite a complicated parser/interpreter ( given that you can embed code inside a Django template ). &lt;br /&gt;
&lt;br /&gt;
Overkill for a &lt;pk&gt;printf()&lt;/pk&gt; like requirement&lt;br /&gt;
&lt;br /&gt;
Still, this was not ideal - every refresh still led to rebuilding the HTML table even if nothing changed from the previous refresh.&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Lesson 2 - Use incremental updates&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, some kind of incremental update was needed. Ideally we would like only a delta to be fetched from the server, but practically there were difficulties implementing this serverside. &lt;br /&gt;
&lt;br /&gt;
The time taken by the server to send off the entire job data was negligible, as was the time taken by the browser to deserialize it into JSON, so there was not much gain to be had from trying to d/dt the data on the server side.&lt;br /&gt;
&lt;br /&gt;
Instead we could do the diff on the client side. It was fairly simple and fast to do this - given the latest job data, and the previous one, we can generate the diff as additions, deletions and changes ( pseudo code below )&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;for(&lt;/pk&gt;i in old&lt;pk&gt;)&lt;/pk&gt; 
    &lt;pk&gt;if(&lt;/pk&gt;not i in new&lt;pk&gt;)&lt;/pk&gt; 
        removed.add&lt;pk&gt;(&lt;/pk&gt;i&lt;pk&gt;)&lt;/pk&gt;

&lt;pk&gt;for(&lt;/pk&gt;i in new&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;if(&lt;/pk&gt;not i in old&lt;pk&gt;)&lt;/pk&gt; 
        added.add&lt;pk&gt;(&lt;/pk&gt;i&lt;pk&gt;)&lt;/pk&gt;  

&lt;pk&gt;for(&lt;/pk&gt;i in new&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;if(&lt;/pk&gt;&lt;pk&gt;(&lt;/pk&gt;i in old&lt;pk&gt;)&lt;/pk&gt; and old[i] != new[i]&lt;pk&gt;)&lt;/pk&gt;
        changed.add&lt;pk&gt;&lt;pk&gt;(&lt;/pk&gt;&lt;/pk&gt;i&lt;pk&gt;)&lt;/pk&gt;  
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The data are in the form of a dictionary keyed by a job number, and each value is in turn a dictionary.(Yes, we know JS doesn&#39;t &lt;em&gt;really&lt;/em&gt; have dictionaries, only objects or whatever!)&lt;br /&gt;
&lt;br /&gt;
The data looks like this :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;{&lt;/pk&gt; 1234 : &lt;pk&gt;{&lt;/pk&gt; job_name: &quot;abcd_xyz8765&quot;,  job_time : &quot;10:24:05&quot; ... &lt;pk&gt;}&lt;/pk&gt; &lt;pk&gt;}&lt;/pk&gt;,
&lt;pk&gt;{&lt;/pk&gt; 1230 : &lt;pk&gt;{&lt;/pk&gt; job_name: &quot;abcd_xyz9645&quot;,  job_time : &quot;01:04:39&quot; ... &lt;pk&gt;}&lt;/pk&gt; &lt;pk&gt;}&lt;/pk&gt; ...
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The best way to compare two objects in JS seems to be to &lt;pk&gt;JSON.stringify(&lt;pk&gt;)&lt;/pk&gt;&lt;/pk&gt; them and do a string compare. Checking each field individually doesn&#39;t seem to be any faster, and may be even slower, considering that each member access will cause a dictionary lookup.&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Lesson 3 - Know your data&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are 5 scenarios that happen :&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Initial page load, any number of rows get added - this happens only at login, but makes the most psychological impact in terms of how snappy the site seems.&lt;/li&gt;
&lt;li&gt;Periodic refresh, a few rows change state - but if the UI is busy during the update, it feels sluggish.&lt;/li&gt;
&lt;li&gt;User adds a job, one row gets changed.&lt;/li&gt;
&lt;li&gt;User terminates one or more jobs, any number of rows chage state.&lt;/li&gt;
&lt;li&gt;User removes one or more jobs.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The add case is the most important even though it happens only once per session.&lt;br /&gt;
&lt;br /&gt;
The table is always sorted based on a job index, in descending order, so it becomes necessary to insert any new rows into the right locations. &lt;br /&gt;
The following simple approach acts like an insertion sort, which is extremely slow. &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;for(&lt;/pk&gt;job in newjob&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    &lt;pk&gt;for(&lt;/pk&gt;row in rows&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;{&lt;/pk&gt;
        &lt;pk&gt;if(&lt;/pk&gt;row.jobindex &amp;lt; job.index&lt;pk&gt;)&lt;/pk&gt;
        &lt;pk&gt;{&lt;/pk&gt;
            insertBefore&lt;pk&gt;(&lt;/pk&gt;row, makerow&lt;pk&gt;(&lt;/pk&gt;job&lt;pk&gt;)&lt;/pk&gt;&lt;pk&gt;)&lt;/pk&gt;;
            break;
        &lt;pk&gt;}&lt;/pk&gt;
    &lt;pk&gt;}&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
For every new row, its insertion location needs to be found in the table. Sure, we could conceivably make the above into a binary search. Not non-trivial, but still a mass of code.&lt;br /&gt;
Even then, we have to insert elements in the middle of a table, which is slow.&lt;br /&gt;
&lt;br /&gt;
After much head scratching, I realized, I don&#39;t even need to do this - The job indices in the server are unique and always increasing. The data is also always sorted ( because it ends up in a JSON dictionary sorted by job index ). &lt;br /&gt;
&lt;br /&gt;
If we just ensure that the job data is in the same sort order as the table, we can avoid all the above slowness/complexity.  &lt;br /&gt;
&lt;br /&gt;
So for case 1, just appending each row is fine. &lt;br /&gt;
&lt;br /&gt;
For case 3, a new job will always end up right at the top of the table, since a new job will always have an index greater than any job previously seen.    &lt;br /&gt;
&lt;br /&gt;
So we can write something like : &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;if(&lt;/pk&gt;table.isempty&lt;pk&gt;()&lt;/pk&gt;&lt;pk&gt;)&lt;/pk&gt;  // case 1
&lt;pk&gt;{&lt;/pk&gt;
    &lt;pk&gt;for(&lt;/pk&gt;job in newjob&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;{&lt;/pk&gt;
        row = makerow&lt;pk&gt;(&lt;/pk&gt;job&lt;pk&gt;)&lt;/pk&gt;;
        table.append&lt;pk&gt;(&lt;/pk&gt;row&lt;pk&gt;)&lt;/pk&gt;;
    &lt;pk&gt;}&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
else                // case 3
&lt;pk&gt;{&lt;/pk&gt;
    &lt;pk&gt;for(&lt;/pk&gt;job in newjob&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;{&lt;/pk&gt;
        row = makerow&lt;pk&gt;(&lt;/pk&gt;job&lt;pk&gt;)&lt;/pk&gt;;
        table.prepend&lt;pk&gt;(&lt;/pk&gt;row&lt;pk&gt;)&lt;/pk&gt;;
    &lt;pk&gt;}&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
A huge amount of unnecessary work in finding where a job fits in the table is avoided and appending, rather than inserting elements into the DOM is way faster too.&lt;br /&gt;
This was good for a speedup of more than 2x for case 1. &lt;br /&gt;
Case 3 conceivably never requires more than one row insertion - jobs are started one at a time, so the time is negligible.&lt;br /&gt;
&lt;br /&gt;
Deletion also initially was very slow, because the initial code was something like this&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;for(&lt;/pk&gt;job in deljobs&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    row = findRowWithJobIndex&lt;pk&gt;(&lt;/pk&gt;job.index&lt;pk&gt;)&lt;/pk&gt;;
    row.remove&lt;pk&gt;()&lt;/pk&gt;;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;pk&gt;findRowWithJobIndex()&lt;/pk&gt; used jQuery with the &lt;pk&gt;find&lt;/pk&gt;&lt;pc&gt;&lt;pk&gt;(&lt;/pk&gt;&#39;[key=value]&#39;&lt;pk&gt;)&lt;/pk&gt;&lt;/pc&gt; selector, which is terribly slow, since it &lt;em&gt;has&lt;/em&gt; to be a linear search.&lt;br /&gt;
&lt;br /&gt;
One again, knowing that the deljobs array has descending job indices and so do the table rows, we end up with a much faster delete :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;i = 0;
&lt;pk&gt;for(&lt;/pk&gt;row in rows&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    &lt;pk&gt;if(&lt;/pk&gt;i &amp;lt; deljobs.length&lt;pk&gt;)&lt;/pk&gt;
    &lt;pk&gt;{&lt;/pk&gt;
        &lt;pk&gt;if(&lt;/pk&gt;row.jobindex == deljobs[i]&lt;pk&gt;)&lt;/pk&gt;
        &lt;pk&gt;{&lt;/pk&gt;
            row.remove&lt;pk&gt;()&lt;/pk&gt;;
            i++;
        &lt;pk&gt;}&lt;/pk&gt;
    &lt;pk&gt;}&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
We are essentially doing only one linear pass on the rows and picking off each one that needs to be removed. &lt;br /&gt;
&lt;br /&gt;
More than 5x speedup when deleting all the rows, and close to 10x on IE 11&lt;br /&gt;
&lt;br /&gt;
Simple fast code, resulting from using knowledge about the data, rather than using a catch-all generic algorithm.&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Lesson 4 - Profile&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can only get so far with logic optimization, eventually you have to profile, IE 11 has a very nice profiler, as does Chrome.&lt;br /&gt;
&lt;br /&gt;
I believed the JSON parsing and delta generation code, the HTML template rendering etc. would be very slow, but all that took very little time!&lt;br /&gt;
&lt;br /&gt;
After profiling, the major performance bottlenecks were (surprisingly) :&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;DOM node creation&lt;/li&gt;
&lt;li&gt;jQuery in loops&lt;/li&gt;
&lt;li&gt;Adding, removing and testing for class names in DOM elements&lt;/li&gt;
&lt;/ul&gt;Assigning HTML strings to innerHTML is very slow on IE - It stands to reason, the browser has to parse HTML and make it into DOM objects, and pasring fully spec&#39;d HTML is going to be super slow (Chrome does it real fast though!)&lt;br /&gt;
&lt;br /&gt;
The alternative is to create the DOM elements using code like this :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;var tr = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;tr&#39;&lt;pk&gt;)&lt;/pk&gt;;
var td1 = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;td&#39;&lt;pk&gt;)&lt;/pk&gt;;
td1.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;class&#39;, &#39;job-detail&#39;&lt;pk&gt;)&lt;/pk&gt;;

var td1a = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;a&#39;&lt;pk&gt;)&lt;/pk&gt;;
td1a.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;class&#39;, &#39;job-link&#39;&lt;pk&gt;)&lt;/pk&gt;;
td1a.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;href&#39;, &#39;#&#39;&lt;pk&gt;)&lt;/pk&gt;;

var td2 = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;td&#39;&lt;pk&gt;)&lt;/pk&gt;;
td2.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;class&#39;, &#39;text-center&#39;&lt;pk&gt;)&lt;/pk&gt;;

var td3 = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;td&#39;&lt;pk&gt;)&lt;/pk&gt;;
td3.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;class&#39;, &#39;text-center&#39;&lt;pk&gt;)&lt;/pk&gt;;

var td4 = document.createElement&lt;pk&gt;(&lt;/pk&gt;&#39;td&#39;&lt;pk&gt;)&lt;/pk&gt;;
td4.setAttribute&lt;pk&gt;(&lt;/pk&gt;&#39;class&#39;, &#39;text-center&#39;&lt;pk&gt;)&lt;/pk&gt;;

tr.appendChild&lt;pk&gt;(&lt;/pk&gt;td1&lt;pk&gt;)&lt;/pk&gt;;
tr.appendChild&lt;pk&gt;(&lt;/pk&gt;td2&lt;pk&gt;)&lt;/pk&gt;;
tr.appendChild&lt;pk&gt;(&lt;/pk&gt;td3&lt;pk&gt;)&lt;/pk&gt;;
tr.appendChild&lt;pk&gt;(&lt;/pk&gt;td4&lt;pk&gt;)&lt;/pk&gt;;
td1.appendChild&lt;pk&gt;(&lt;/pk&gt;td1a&lt;pk&gt;)&lt;/pk&gt;;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
However, this is just as slow as innerHTML even though a number of synthetic benchmarks show otherwise on the web. But the profiler does not lie.&lt;br /&gt;
&lt;br /&gt;
The answer is that we need to create this node just once, and clone copies of it with &lt;pk&gt;cloneNode&lt;pk&gt;()&lt;/pk&gt;&lt;/pk&gt; when we need more. &lt;br /&gt;
&lt;br /&gt;
In fact doing that means we can possibly keep the template inside the easily tweakable HTML, instead of in the above opaque JS code.&lt;br /&gt;
Using this approach improves the node creation performance extremely, leaving &lt;pk&gt;appendChild&lt;pk&gt;()&lt;/pk&gt;&lt;/pk&gt; as the main laggard.&lt;br /&gt;
&lt;br /&gt;
There are hordes of JS performance blogs (including one by John Resig&lt;pk&gt;)&lt;/pk&gt; which hint that great speedup can be had by using &lt;pk&gt;createDocumentFragment&lt;pk&gt;()&lt;/pk&gt;&lt;/pk&gt;, appending many nodes to that, and then appending the fragment to the main DOM. &lt;br /&gt;
&lt;br /&gt;
However on both Chrome and IE 11, this approach has worse performance. Browsers have evolved a lot since the days of IE 8 and we&#39;re not in Kansas anymore.&lt;br /&gt;
The profiler is the ultimate authority, despite any number of 3rd party benchmarks showing the contrary.&lt;br /&gt;
&lt;br /&gt;
After a lot of experimentation, I found that there is probably no straightforward way to speed up &lt;pk&gt;appendChild(&lt;pk&gt;)&lt;/pk&gt;&lt;/pk&gt;.&lt;br /&gt;
Now it&#39;s all the browsers fault!&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
The second bottleneck is &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
jQuery&#39;s &lt;pk&gt;$(elem)&lt;/pk&gt; &lt;pk&gt;function&lt;/pk&gt; does a huge amount of work. Whenever you need to do it more than once, it makes sense to use the raw DOM methods instead, even if it involves more verbose code. jQuery makes for compact neat code, but performance is dismal. &lt;br /&gt;
&lt;br /&gt;
&lt;pk&gt;$(&#39;.someclass&#39;)&lt;/pk&gt; can be terribly slow - it is much faster to iterate over all the elements and check for the class. &lt;br /&gt;
The reasoning is that jQuery (or the corresponding DOM method) is going to iterate over some data structure anyway, and do some work with each element so it can give it back to you. &lt;br /&gt;
I am not quite sure, but it seems like this is linear on the number of elements - It could conceivably be a &lt;pk&gt;log N&lt;/pk&gt; operation, but who knows?&lt;br /&gt;
&lt;br /&gt;
Instead you can iterate yourself over the elements using &lt;pk&gt;elem.children[]&lt;/pk&gt; and do the work in one shot if the classname matches. Even more so if you need to test for things other than the classname, like attribute values.&lt;br /&gt;
&lt;br /&gt;
&lt;pk&gt;$(elem).find(&#39;[key=value]&#39;)&lt;/pk&gt; should be avoided like the plague, if elem has hundreds of child elements&lt;br /&gt;
&lt;br /&gt;
The ideal framework to use for performance is &lt;a href=&quot;http://daringfireball.net/&quot;&gt;Vannilla.js&lt;/a&gt; where possible.&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
The third bottleneck is dealing with DOM element classnames.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;pk&gt;$(elem).addClass(&#39;someclass&#39;)&lt;/pk&gt; is slow&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;elem.className += &#39; someclass&#39;&lt;/pk&gt; is not much faster&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;elem.classList.add(&#39;someclass&#39;)&lt;/pk&gt; is the fastest method&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;elem.classList[n] != null&lt;/pk&gt; is the best way to test for a class name, if the position of that classname is fixed&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;elem.classList.has(&#39;classname&#39;)&lt;/pk&gt; is the next best&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
This was used in the table row selection code, and this, along with some other tweaks mentioned below took the speed of selection from 14 seconds for 900 rows on IE 11 to 0.12 seconds - a 100x speedup!&lt;br /&gt;
&lt;br /&gt;
On Chrome it was not as dramatic, but the times dropped out to below whats measurable accurately, but certainly from 120 ms to about 5 ms.&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Lesson 5 - Old tricks always work&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are a few simple habits that you develop when writing high performance code in static languages, these actually spill over even to dynamic languages, with greater effect&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;pk&gt;&lt;em&gt;If you use an expression more than once&lt;/em&gt;&lt;/pk&gt; : make it a variable &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
For example when you see:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;if(&lt;/pk&gt;row[i].classList.contains&lt;pk&gt;(&lt;/pk&gt;&#39;class1&#39;&lt;pk&gt;)&lt;/pk&gt;&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    row[i].classList.add&lt;pk&gt;(&lt;/pk&gt;&#39;class1&#39;&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
You should realize that every &lt;pk&gt;[]&lt;/pk&gt; and &lt;pk&gt;.&lt;/pk&gt; is a potential bottleneck.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;var cls = row[i].classList
&lt;pk&gt;if(&lt;/pk&gt;cls.contains&lt;pk&gt;(&lt;/pk&gt;&#39;class1&#39;&lt;pk&gt;)&lt;/pk&gt;&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    cls.add&lt;pk&gt;(&lt;/pk&gt;&#39;class1&#39;&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
will be faster&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;pk&gt;&lt;em&gt;Arrays are fast&lt;/em&gt;&lt;/pk&gt; : when in doubt use an array.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Cache it if you can&lt;/em&gt;&lt;/pk&gt; : If you have something generated by a large chunk of code, hang on to it for later - its easier to know if an answer changed than recalculate it. Applies very much to dynamic langauges since they are bound by CPU speed rather than memory access speed.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Pull invariant code out of loops&lt;/em&gt;&lt;/pk&gt; : The compiler does this for you in static languages. In dynamic languages you need to do it yourself.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Avoid dynamic allocation&lt;/em&gt;&lt;/pk&gt; : Hard to tell in a dynamic language when it doesn&#39;t happen, but be aware of when it can happen - reuse objects instead of making new ones. Allocation may be very fast, but constrution can be very heavy in a language like JS - This is why jQuery $(elem) is so bad.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Optimize the worst case&lt;/em&gt;&lt;/pk&gt; : If the worst case is frequent enough to be noticed, optimize that at the expense of the average or best case. Mike Abrash said the same.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Make it look fast, even if it is incurably slow&lt;/em&gt;&lt;/pk&gt; : This is psychology - a console tool that shows progress with a fast \|/-\ spinner appears way faster than something that shows a 0 to 100 progress indicator. Microsoft knows this, which is why progress bars animate as well as move forward.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pk&gt;&lt;em&gt;Optimize multiple condition &lt;pk&gt;if&lt;/pk&gt;() statements&lt;/em&gt;&lt;/pk&gt; :  When testing for various things with &amp;amp;&amp;amp; and ||, try to order the conditions in a way that maximizes the short circuit of the operator.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
For example when you have:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;if(&lt;/pk&gt;leastLikely || lessLikely || likely&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    ...
&lt;pk&gt;}&lt;/pk&gt;

&lt;pk&gt;if(&lt;/pk&gt;!likely || !lessLikely || !leastLikely&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    ...
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The conditions are evaluated maximum number of times, instead the following :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&#39;code&#39;&gt;&lt;pre&gt;&lt;pi&gt;&lt;pk&gt;if(&lt;/pk&gt;likely ||  lessLikely || leastLikely&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    ...
&lt;pk&gt;}&lt;/pk&gt;

&lt;pk&gt;if(&lt;/pk&gt;!leastLikely || !lessLikely || !likely&lt;pk&gt;)&lt;/pk&gt;
&lt;pk&gt;{&lt;/pk&gt;
    ...
&lt;pk&gt;}&lt;/pk&gt;
&lt;/pi&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
will be faster, especially if the three conditions are expressions rather than values, and in any case, due to branch prediction. &lt;br /&gt;
&lt;br /&gt;
All these little tweaks shave off a few dozen milliseconds here and there and it adds up. The trick is to make this simple stuff a reflex.&lt;br /&gt;
&lt;br /&gt;
&lt;hr/&gt;&lt;b class=&quot;headin&quot;&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It seems like the effects of basic optimization are amplified highly when using dynamic languages. You can get away with a lot of inefficiency in static languages - the compiler works really hard to offset your stupidity, but in dynamic languages, it gets thrown back in your face. &lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/3159997396096348683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2014/07/a-dom-of-many-hovered-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3159997396096348683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/3159997396096348683'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2014/07/a-dom-of-many-hovered-class.html' title='A DOM of many hovered class'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-7816733709446342721</id><published>2014-06-21T12:07:00.000-07:00</published><updated>2014-06-21T12:07:37.786-07:00</updated><title type='text'>Embracing the hate : python, JS, node.js, </title><content type='html'>&lt;span style=&quot;font-size: large;&quot;&gt;For a few months now, I have been working mostly with web based code, migrating nacc.nimbix.net from node.js/coffeescript to django/python, and extending the website.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;The abomination that is node.js and the ugliness that is coffeescript needs another post in itself. And the monstrosity that is Bootstrap, I&#39;ve learned to live with, since I just copied the entire CSS and HTML for the new portal.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;The first few weeks I had to add certain features to the existing website, to somehow grok through the coffeescript and understand what does what.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The first stumbling block was the &quot;almost but not quite&quot; javascript syntax of coffeescript. I can understand inventing a new syntax if your programming paradigm is extremely different from existing languages, but a whitespace significant, functional looking style is absolutely mismatched for a very imperative, side effect filled application like a web portal.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;The second one was the fact that it&#39;s hard to tell in a node application which part executes on the server and which on the client. In making it seem seamless across client and server, you have no idea what&#39;s happening at the HTTP level.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;All that is history however, since I moved everything to django, but then jade/less came to bite me - all the CSS was in the form of .less and all the HTML in the form of .jade files. I tried many tools to try converting the code, but everything failed. Even the server on which the actual node application ran, I was not able to get the jade/less files convert to HTML/CSS due to various incomprehensible reasons.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Finally I found a windows based tool and managed to batch convert everything.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;Now I was all set to tango with django, but after programming in static typed C++ for more than a decade, it seemed like building out of green bamboo after concrete and steel, dealing with JS and python.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;The saving grace was that the model is simple and straightforward - you have URLs that map to python functions that render the HTML you need. None of that over-complicated enterprise stuff that you find in high level frameworks. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;Database ORM was reasonably reasonable, although getting existing database queries to map to django&#39;s model is quite a head scratcher. Thank heavens for stackoverflow!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;Intellisense is pathetic for dynamic languages. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;I was trained under a regimen of Delphi, Visual Studio and Eclipse and expect code to write 40% of itself. Half the time, if intellisense works right, you don&#39;t have to look at the documentation for APIs, otherwise it degenerates into a continuous cycle of looking on google for methods you believe &quot;should&quot; exist and often you may never realize a particular functionality exists.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;For e.g. who would think that the method used to remove elements from an array is called splice() in JS? How do you add something to an array, is it push(), append(), add() or what? Intellisense, when it works, tells you what methods an object has. However intellisense is theoretically impossible to do perfectly in a dynamic language.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;In some ways JS and python are deviously similar, but it&#39;s a trap:&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Is it &lt;b&gt;&#39; &#39;.join[&#39;1&#39;,&#39;2&#39;,&#39;3&#39;]&lt;/b&gt; or is it &lt;b&gt;[1, 2, 3].join(&#39; &#39;)&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Is it &lt;b&gt;arr.length&lt;/b&gt; or is it &lt;b&gt;len(arr)&lt;/b&gt; ?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Is it &lt;b&gt;for(i in items)&lt;/b&gt; or is it &lt;b&gt;for i in items&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Is whitespace significant or not? Surprisingly, in JS whitespace is not significant, however, newlines are significant and a misplaced one can cause syntax errors or even code that doesn&#39;t do what it seems to.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;It&#39;s frustrating and annoying....&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;Of course some things are cool, like the [:] array slicing syntax in python but then there are numerous annoyances mostly because of the dynamic nature of the language&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Numbers are floating point in JS, you have to bitwise or it with 0 to get an integer, and this is idiomatic!&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;You misspell a variable being assigned to and it simply refers to a new one. The last time I saw that was in BASIC and a it&#39;s a wellspring of errors. Silly mistakes and typos should not require runtime debugging!&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Variable scoping is &lt;i&gt;&lt;b&gt;weird&lt;/b&gt;&lt;/i&gt; in JS&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Pass arguments by value but pass object arguments by reference - &lt;b&gt;But, &lt;/b&gt;strings are objects, yet they act like values. The only thing worse is passing everything by reference like in FORTRAN.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Performance anxiety - you can&#39;t really get a sense for how fast something is going to run. It may be super-optimized due to the VM, or it may be horribly inefficient. There&#39;s a continuous worry about slowdowns (and it is a valid worry, when we&#39;re talking like 5 to 20 times slower than C++). I had no idea that using &lt;b&gt;map()&lt;/b&gt; is faster in python than a loop. There would be no valid reason in a static language for something like that - iteration is iteration&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The saving grace is that the latest ECMAScript 6 standard brings a lot of progress to JS and makes it possible to use a much more saner subset of the language.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-size: large;&quot;&gt;Python 3 promises much but since they break compatibility it looks bleak.&lt;br /&gt;
&lt;br /&gt;
For now I simply follow grumpy cats advice :&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgj2AINon970qH8OMebKD_vilDoKKTt03okGLkhTAAUpQG38cH04kAWX2F3lXNTVZuetfHBpvz8b-LfeNYZ-xeIolGi9pwrj-Egm-v4ztuvLK-WEE8DKuUgxO0jX4VVQEoEuEw03ucdz4/s1600/grumpy-cat-sith.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgj2AINon970qH8OMebKD_vilDoKKTt03okGLkhTAAUpQG38cH04kAWX2F3lXNTVZuetfHBpvz8b-LfeNYZ-xeIolGi9pwrj-Egm-v4ztuvLK-WEE8DKuUgxO0jX4VVQEoEuEw03ucdz4/s1600/grumpy-cat-sith.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/7816733709446342721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2014/06/embracing-hate-python-js-nodejs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7816733709446342721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/7816733709446342721'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2014/06/embracing-hate-python-js-nodejs.html' title='Embracing the hate : python, JS, node.js, '/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgj2AINon970qH8OMebKD_vilDoKKTt03okGLkhTAAUpQG38cH04kAWX2F3lXNTVZuetfHBpvz8b-LfeNYZ-xeIolGi9pwrj-Egm-v4ztuvLK-WEE8DKuUgxO0jX4VVQEoEuEw03ucdz4/s72-c/grumpy-cat-sith.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-6804129423336480664</id><published>2012-07-23T02:27:00.000-07:00</published><updated>2012-07-23T02:28:20.721-07:00</updated><title type='text'>Tales from the crypt - Cross linked partition tables</title><content type='html'>&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;Back in 1999 I happened to own a DX4 100 ( That&#39;s a clock tripled 486 processor) based system. I ran a dual boot with Windows 98 and Redhat Linux 6.1 on a small 2 GB hard drive.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;The system had 32 MB of RAM and I used about 100 MB of page file for Windows on a separate partition. A huge annoyance was the fact that I needed to also allocate precious space for Linux to swap on. I could have made Linux use the same file as a swap space, but there was some article about how it&#39;s better to use a whole partition. Using that partition as swap for Linux would make Windows no longer recognize it as a file system.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;So I decided to do something quite dangerous, at the risk of destroying all my data. I decided to create a cross linked partition table.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;Using Peter Norton&#39;s Diskedit (Wasn&#39;t it just amazing how it brought up a graphics mouse pointer while still appearing to be in text mode?) I added a new partition entry, and pointed it to a range that lived within the page file of the Windows installation.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;After booting into Linux, I used dd to backup a sector from that new partition (just in case), and then overwrote that with 0s. Reading the page file on the Windows swap partition showed the same block of 0s I had just written.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;I added a mkswap and swapon command to the init scripts and and things worked perfectly on Linux.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;Windows ran perfectly too, oblivious to the fact that the page file was doing double duty.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: large;&quot;&gt;A dangerous and crazy trick, but it did the job for a long time, until I got a 4.3 gig drive.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/6804129423336480664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2012/07/tales-from-crypt-cross-linked-partition.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/6804129423336480664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/6804129423336480664'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2012/07/tales-from-crypt-cross-linked-partition.html' title='Tales from the crypt - Cross linked partition tables'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-2292031676581136783</id><published>2012-02-06T03:52:00.000-08:00</published><updated>2012-02-06T11:29:33.816-08:00</updated><title type='text'>C++ and beyond - The power of abstractions</title><content type='html'>&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
.post-body { line-height:1.25;}
pc { color: #00FF00; font-style: italic; }
pf { color: #00FF00; }
pi { color: #FF8000; }
pn { color: #00FF00; }
pk { color: #FFFF00; font-weight: bold; }
ps { color: #FF8000; }
txo { color: orange;}
txy { color: yellow;}
.code { color: orange; font-size: x-large; border-style:solid; border-width:1px; padding:0px; margin:0px; }
.serif {font-family: serif; font-size: large;}
.li { color: orange; margin: 0px; padding: 0px; line-height:1.25;}
.ul {font-family: serif; font-size: large;}
pre { padding:0px; margin:8px;}
.headin { color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;}
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;div class=&quot;serif&quot;&gt;&lt;b class=&quot;headin&quot;&gt;Modern C++ &lt;/b&gt;&lt;br /&gt;
I&#39;ve been primarily a C++ programmer, even though I have dabbled with Assembler, C, Object Pascal, Java, C#, and Javascript (in that order, chronologically). Over the years, I learned to adapt my style as much as possible from the &quot;C with classes&quot; style to &quot;C++ with STL&quot; to &quot;Modern C++&quot;.&lt;br /&gt;
There&#39;s a lot of awesome material online from &lt;txo&gt;Andrei Alexandrescu, Herb Sutter, Bjarne Stroustrup and Scott Meyers&lt;/txo&gt;, that mostly popular since the C++0x standard came into the light and after looking at those, my understanding of the C++ toolbox improved quite a bit.&lt;br /&gt;
&lt;br /&gt;
One of the oft repeated tenets in the modern C++ community is that well written generic code using type-rich templates will produce faster code than C style if used properly. I always took this on faith, since the people who claim this (like the above 4 gentlemen) have forgotten more C++ than I ever learned.&lt;br /&gt;
&lt;br /&gt;
Now that I started work on &lt;txo&gt;BABEL&lt;/txo&gt;, I decided to test this out and see with my own eyes, if modern C++ with abstract,type-rich idioms can beat plain old C style code, while remaining extremely high level and readable.&lt;br /&gt;
&lt;br /&gt;
&lt;b class=&quot;headin&quot;&gt;A numerical sequence class &lt;/b&gt;&lt;br /&gt;
I often deal with problems that involve the use of intervals or ranges... I wanted to create an abstraction that lets me deal with these in a simple manner.&lt;br /&gt;
&lt;br /&gt;
Thus I want a type that holds a range like &lt;txo&gt;[begin, end)&lt;/txo&gt; and define operator overloads and other member functions for slicing, disjunction and so on. One useful feature would be to have it support an iterator interface, so that it plugs into STL numeric algorithms easily.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s the basic public interface I ended up with :&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;template&lt;/pk&gt;&amp;#60;&lt;pk&gt;typename &lt;/pk&gt;t&amp;#62; &lt;pk&gt;struct &lt;/pk&gt;TNumSeq
{
&lt;pk&gt;public:&lt;/pk&gt;
    &lt;pk&gt;friend &lt;/pk&gt;&lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;&lt;pk&gt;bool &lt;/pk&gt;&lt;/pk&gt;&lt;pk&gt;operator&lt;/pk&gt;&amp;#60;(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;range, &lt;pk&gt;const &lt;/pk&gt;T &amp;val);
    &lt;pk&gt;friend &lt;/pk&gt;&lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;&lt;pk&gt;bool &lt;/pk&gt;&lt;/pk&gt;&lt;pk&gt;operator&lt;/pk&gt;&amp;#62;(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;range, &lt;pk&gt;const &lt;/pk&gt;T &amp;val);
    &lt;pk&gt;friend &lt;/pk&gt;&lt;pk&gt;inline &lt;/pk&gt;TNumSeq &lt;pk&gt;operator&lt;/pk&gt;&amp;(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;seq1, &lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;seq2);
    &lt;pk&gt;friend &lt;/pk&gt;&lt;pk&gt;inline &lt;/pk&gt;TNumSeq &lt;pk&gt;operator&lt;/pk&gt;&amp;(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;seq, T val);
    &lt;pk&gt;friend &lt;/pk&gt;&lt;pk&gt;inline &lt;/pk&gt;TNumSeq &lt;pk&gt;operator&lt;/pk&gt;&amp;(T val, &lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;seq);

    &lt;pk&gt;inline &lt;/pk&gt;TNumSeq();
    &lt;pk&gt;inline &lt;/pk&gt;TNumSeq(&lt;pk&gt;const &lt;/pk&gt;T &amp;b, &lt;pk&gt;const &lt;/pk&gt;T &amp;e);
    &lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;explicit &lt;/pk&gt;TNumSeq(&lt;pk&gt;const &lt;/pk&gt;T &amp;b);
    &lt;pk&gt;inline &lt;/pk&gt;TNumSeq &amp;&lt;pk&gt;operator&lt;/pk&gt;=(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;that);
    &lt;pk&gt;inline &lt;/pk&gt;TNumSeq&amp; &lt;pk&gt;operator&lt;/pk&gt;&amp;=(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;that);
    &lt;pk&gt;inline &lt;/pk&gt;TNumSeq &lt;pk&gt;operator&lt;/pk&gt;&amp;(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;that);

    &lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;&lt;pk&gt;bool &lt;/pk&gt;&lt;/pk&gt;has(&lt;pk&gt;const &lt;/pk&gt;T&amp; val) &lt;pk&gt;const;&lt;/pk&gt;
    &lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;operator&lt;/pk&gt; bool() &lt;pk&gt;const;&lt;/pk&gt;

    class const_iterator : &lt;pk&gt;public &lt;/pk&gt;std::iterator&amp;#60;std::&lt;pk&gt;for&lt;/pk&gt;ward_iterator_tag, T&amp;#62;
    {
    &lt;pk&gt;public:&lt;/pk&gt;
        const_iterator(&lt;pk&gt;const &lt;/pk&gt;TNumSeq &amp;seq, &lt;pk&gt;const &lt;/pk&gt;T &amp;inc, &lt;pk&gt;const &lt;/pk&gt;T &amp;val);
        &lt;pk&gt;inline &lt;/pk&gt;T &lt;pk&gt;operator&lt;/pk&gt;*() &lt;pk&gt;const;&lt;/pk&gt;
        &lt;pk&gt;inline &lt;/pk&gt;const_iterator &lt;pk&gt;operator&lt;/pk&gt;++(&lt;pk&gt;int&lt;/pk&gt;);
        &lt;pk&gt;inline &lt;/pk&gt;const_iterator &amp;&lt;pk&gt;operator&lt;/pk&gt;++();
        &lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;&lt;pk&gt;bool &lt;/pk&gt;&lt;/pk&gt;&lt;pk&gt;operator&lt;/pk&gt;==(&lt;pk&gt;const &lt;/pk&gt;const_iterator &amp;that) &lt;pk&gt;const;&lt;/pk&gt;
        &lt;pk&gt;inline &lt;/pk&gt;&lt;pk&gt;&lt;pk&gt;bool &lt;/pk&gt;&lt;/pk&gt;&lt;pk&gt;operator&lt;/pk&gt;!=(&lt;pk&gt;const &lt;/pk&gt;const_iterator &amp;that) &lt;pk&gt;const;&lt;/pk&gt;
    };

    const_iterator begin(T inc = 1) &lt;pk&gt;const;&lt;/pk&gt;
    const_iterator end(T inc = 1) &lt;pk&gt;const;&lt;/pk&gt;
};
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
It&#39;s quite simple, you can define a numeric range, use the &lt;txo&gt;&amp;lt;&lt;/txo&gt; and &lt;txo&gt;&amp;gt;&lt;/txo&gt; operators to check if a value or another range is outside the range on either side, you can use &lt;txo&gt;&amp;amp;&lt;/txo&gt; to get the part of a range that overlaps with another.&lt;br /&gt;
&lt;br /&gt;
Empty ranges work fine, implicit bool conversion&lt;txo&gt;(Danger! Will Robinson)&lt;/txo&gt; checks for emptiness. The &lt;txo&gt;has()&lt;/txo&gt; member gives you membership test. And there is a forward &lt;txo&gt;const_iterator&lt;/txo&gt; that lets this class masquerade as if the sequence were a real set of stored integers. The &lt;txo&gt;begin()&lt;/txo&gt; and &lt;txo&gt;end()&lt;/txo&gt; functions take a stepping increment for iteration by any &quot;jump&quot;.&lt;br /&gt;
&lt;br /&gt;
So to test this out... I tested the following code :&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;int&lt;/pk&gt; i = 0, j = 1 &amp;#60;&amp;#60; 30, sum = 0;
&lt;pk&gt;for&lt;/pk&gt;(&lt;pk&gt;int&lt;/pk&gt; n = i; n &amp;#60; j; n ++)
{
    sum += n;
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
versus&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;int&lt;/pk&gt; i = 0, j = 1 &amp;#60;&amp;#60; 30;
TNumSeq&amp;#60;&lt;pk&gt;int&lt;/pk&gt;&amp;#62; s(i, j);
&lt;pk&gt;int&lt;/pk&gt; sum = std::accumulate(s.begin(), s.end(), 0);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
Ignore the fact that the default int will overflow the summation, for the range &lt;txo&gt;0&lt;/txo&gt; to &lt;txo&gt;2^30&lt;/txo&gt;, that&#39;s immaterial for this test.        One (and certainly, yours truly) would imagine that by no stretch of imagination, the generated code for the second example would be faster that the bare bones loop in the first - Look at all that is happening in the &lt;txo&gt;accumulate()&lt;/txo&gt; call : &lt;br /&gt;
&lt;ul style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;&lt;li style=&quot;color: orange;&quot;&gt;Two method invocations to get the iterators, which are at least 12 byte objects, have a constructor, and passed by value to accumulate, thus copying them twice each (apparently).&lt;/li&gt;
&lt;li style=&quot;color: orange;&quot;&gt;A loop inside, which calls the comparison,increment and dereference operators on the iterator object, both of whose implementations contain member access.&lt;/li&gt;
&lt;/ul&gt;Seems like an awfully complicated code path for a very trivial task - but when I timed this I found that the two versions run at the same speed. Go figure!     &lt;br /&gt;
Here is the exact assembly code generated by the compiler for the two cases : &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;009A18E0  &lt;pk&gt;add&lt;/pk&gt;         ecx,eax
009A18E2  &lt;pk&gt;inc&lt;/pk&gt;         eax
009A18E3  &lt;pk&gt;cmp&lt;/pk&gt;         eax,40000000h
009A18E8  &lt;pk&gt;jl &lt;/pk&gt;         testNumSeq+60h (9A18E0h)
&lt;/pre&gt;&lt;/div&gt;versus&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;009A1BE0  &lt;pk&gt;add&lt;/pk&gt;         ecx,eax
009A1BE2  &lt;pk&gt;add&lt;/pk&gt;         eax,esi
009A1BE4  &lt;pk&gt;cmp&lt;/pk&gt;         eax,40000000h
009A1BE9  &lt;pk&gt;jne&lt;/pk&gt;         testNumSeq+360h (9A1BE0h)
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
And for increment by an arbitrary number : &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;00BA18E4  &lt;pk&gt;add&lt;/pk&gt;         ecx,eax
00BA18E6  &lt;pk&gt;add&lt;/pk&gt;         eax,2
00BA18E9  &lt;pk&gt;cmp&lt;/pk&gt;         eax,40000000h
00BA18EE  &lt;pk&gt;jl &lt;/pk&gt;         testNumSeq+64h (0BA18E4h)
&lt;/pre&gt;&lt;/div&gt;versus&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;00BA1BF4  &lt;pk&gt;add&lt;/pk&gt;         ecx,eax
00BA1BF6  &lt;pk&gt;add&lt;/pk&gt;         eax,edx
00BA1BF8  &lt;pk&gt;cmp&lt;/pk&gt;         eax,40000000h
00BA1BFD  &lt;pk&gt;jne&lt;/pk&gt;         testNumSeq+374h (0BA1BF4h)                                                     &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
No difference except the fact that the for loop uses a constant as the increment, whereas the TNumSeq uses a variable on a register as the increment.   How the hell does this happen? It seems like magic, the way that the compiler took away all that 50 odd lines of code in my class and came up with the succinct loop above.   The answer is that it is due to being able to express intention more clearly to the compiler. There are many little things that happen, I will detail a few... &lt;br /&gt;
&lt;ul style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;&lt;li style=&quot;color: orange;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;txy&gt;RVO and move semantics &lt;/txy&gt;&lt;/b&gt;&lt;/i&gt;- The iterator pass by value copying is elided by RVO (return value optimization). With C++11, the move semantics feature takes care of most cases of this at the language level, and whenever an object is moved, it actually reuses the storage and state, rather than copy to a new place and destroy the old one. That means, you can treat any old object, even if it is large as if it were like an int and pass it around by value with impunity, knowing that the language/compiler is taking care of efficiency concerns. No overhead induced or change to existing code!&lt;/li&gt;
&lt;li style=&quot;color: orange;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;txy&gt;const correctness&lt;/txy&gt; &lt;/b&gt;&lt;/i&gt;- since the parent sequence of the iterator is stored within the iterator as a const reference, and the iterator dereference operator is const, The compiler knows that the state of the iterator cannot change durin operator* and that the sequence cannot change during the that as well as operator++. This means it can keep those values in registers. &lt;/li&gt;
&lt;li style=&quot;color: orange;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;txy&gt;template inlining&lt;/txy&gt; &lt;/b&gt;&lt;/i&gt;- templates are not code, they are actually code generators with zero overhead. All the above code becomes a single chunk of some meta-C++ which, unlike the C style code, has information alongside about what the code means. The compiler is able to use this extra information to generate the best possible machine code. Trust me, it&#39;s way more smarter than you or me, when it comes to this. As an assembly programmer I often observe compiler generated machine code to see if there is any scope of improvement and 9 times out of 10, there is none, unless I radically change the algorithm or use vectorization instructions...&lt;/li&gt;
&lt;/ul&gt;So, in conclusion, we can see that writing idiomatic C++ code in a modern way sacrifices nothing, in performance while still providing high level abstractions. This is the future! To quote Sutter from &lt;a href=&quot;http://channel9.msdn.com/Events/GoingNative/GoingNative-2012&quot; target=&quot;_blank&quot; style=&quot;color: Orange;&quot;&gt;&lt;u&gt;GoingNative2012&lt;/u&gt;&lt;/a&gt; &lt;i&gt;&quot;Performance has always been the king, since the entire history of programming, except the last decade,but now it&#39;s &lt;b&gt;&#39;The Return of the king&#39;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;
&lt;div style=&quot;color: yellow;&quot;&gt;&lt;i&gt;&lt;br /&gt;
More on this as i progress with BABEL&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/2292031676581136783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2012/02/c-and-beyond-power-of-abstractions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/2292031676581136783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/2292031676581136783'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2012/02/c-and-beyond-power-of-abstractions.html' title='C++ and beyond - The power of abstractions'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-8444304303335780032</id><published>2012-02-05T10:21:00.000-08:00</published><updated>2012-02-06T04:32:14.307-08:00</updated><title type='text'>The library of babel</title><content type='html'>&lt;div style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;If you haven&#39;t heard of that library, I recommend that you go and read the short story by that name ASAP, pronto, on the double, etc. etc.&lt;br /&gt;
&lt;br /&gt;
This post however is one of a series, where I will document the creation of my own utility library in &lt;text style=&quot;color: orange;&quot;&gt;C++&lt;/text&gt;.&lt;br /&gt;
&lt;b style=&quot;color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
What?&lt;/b&gt;&lt;br /&gt;
One of the biggest and most important steps in creating software, whether  a product or a framework is to name it properly, such that it makes some sense. A recursive acronym as the name is even better.&lt;br /&gt;
&lt;br /&gt;
Since this library will contain everything (in terms of code that I ever needed in more than one project), I call it babel - To expand the recursive acronym - &lt;text style=&quot;color: yellow;&quot;&gt;Babel Attempts Being Everything Literally&lt;/text&gt;&lt;br /&gt;
I don&#39;t intend anyone except me to use it, it&#39;s my little toolbox to do things the way I want them done.&lt;br /&gt;
&lt;br /&gt;
It will be a heterogeneous collection of classes and modules which will include stuff extending the &lt;text style=&quot;color: orange;&quot;&gt;STL&lt;/text&gt;, wrappers and helpers for &lt;text style=&quot;color: orange;&quot;&gt;OpenGL, CUDA, COM, Directshow and DES&lt;/text&gt;.&lt;br /&gt;
Stuff for Data compression, Image and text handling, machine learning and so on. &lt;br /&gt;
&lt;br /&gt;
Whatever I feel I want to include! Anything and Everything.&lt;br /&gt;
&lt;b style=&quot;color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
Why?&lt;/b&gt;&lt;br /&gt;
Why one more library? Especially since there is &lt;text style=&quot;color: orange;&quot;&gt;Loki&lt;/text&gt; and &lt;text style=&quot;color: orange;&quot;&gt;Boost&lt;/text&gt; and &lt;text style=&quot;color: orange;&quot;&gt;QT&lt;/text&gt; and what not, written by far more smarter programmers?&lt;br /&gt;
&lt;br /&gt;
For several reasons :&lt;br /&gt;
&lt;ul style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;&lt;li style=&quot;color: orange;&quot;&gt;Writing a high quality library in C++ is a great exercise to improve coding and abstraction skills. Especially since we have &lt;text style=&quot;color: orange;&quot;&gt;C++11&lt;/text&gt; now and the game is changing fast.&lt;/li&gt;
&lt;li style=&quot;color: orange;&quot;&gt;If an existing powerful library like boost does not do exactly what I wish, it is probably beyond my capability to modify it to do so. And much less fun studying and meddling with existing code, than writing it from scratch.&lt;/li&gt;
&lt;li style=&quot;color: orange;&quot;&gt;There are some things --some trivial and some not-- that &lt;text style=&quot;color: orange;&quot;&gt;BABEL&lt;/text&gt; is planned to implement that no one anywhere else seems to have implemented. &lt;text style=&quot;color: orange;&quot;&gt;BABEL&lt;/text&gt; will be like my own personal workshop - the set of things it will do is probably not present in any one single library. And piecing together parts from different libraries in a program seems very inelegant sometimes.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;b style=&quot;color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
How?&lt;/b&gt;&lt;br /&gt;
Essentially with &lt;text style=&quot;color: orange;&quot;&gt;MS Visual Studio 2010&lt;/text&gt;, using as many &lt;text style=&quot;color: orange;&quot;&gt;C++0x/11&lt;/text&gt; features that I can use to make the code modern.&lt;br /&gt;
The &lt;text style=&quot;color: orange;&quot;&gt;NVCC CUDA compiler&lt;/text&gt; also figures in the mix.&lt;br /&gt;
&lt;br /&gt;
My process for developing features, is to look at a very common task that I often code in my projects, and make an abstraction for that.&lt;br /&gt;
Then I look at how to generalize that and match it to the other parts that already exist.&lt;br /&gt;
I keep repeating this process, sometimes rewriting and extending older code to match the newer stuff better.&lt;br /&gt;
Once in a while I refactor, and try to see how each class or module could utilize the others.&lt;br /&gt;
&lt;b style=&quot;color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
When?&lt;/b&gt;&lt;br /&gt;
I started  building parts of this about a year ago, and there are numerous fragments of useful code that I have in diverse locations, from several years back, which I will slowly assimilate into this.&lt;br /&gt;
&lt;br /&gt;
The idea is after a point, there is such a good toolkit that my projects become a snap to write and I have more time to extend the library.&lt;br /&gt;
&lt;b style=&quot;color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
Where?&lt;/b&gt;&lt;br /&gt;
I&#39;ll eventually put up a git repository on &lt;text style=&quot;color: orange;&quot;&gt;github&lt;/text&gt;, hopefully at least parts of it will be of interest to others.&lt;br /&gt;
I will post about the design and implementation of various parts of it on this blog, as I make progress...&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/8444304303335780032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2012/02/library-of-babel.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/8444304303335780032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/8444304303335780032'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2012/02/library-of-babel.html' title='The library of babel'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-5553373902275204562</id><published>2012-02-04T11:46:00.000-08:00</published><updated>2012-02-06T04:37:18.277-08:00</updated><title type='text'>Big end failure</title><content type='html'>&lt;div style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;Recently I did a project - which involved debugging a mixed &lt;text style=&quot;color: orange;&quot;&gt;.NET/C++&lt;/text&gt; application that was failing on a 64 bit build. Now this was a complicated non-trivial app, that used the &lt;text style=&quot;color: orange;&quot;&gt;Microsoft DirectShow&lt;/text&gt; multimedia framework, and one of the reasons that I was hired, was because I have pretty decent experience with this.&lt;br /&gt;
&lt;br /&gt;
My first line of attack was obviously to check the directshow stuff and while the code wasn&#39;t really to my taste, It seemed to work in &lt;text style=&quot;color: orange;&quot;&gt;32 bit&lt;/text&gt; just fine. The &lt;text style=&quot;color: orange;&quot;&gt;64 bit&lt;/text&gt; build just refused to work. I immediately jumped to the conclusion that there was something to do with the interaction of a &lt;text style=&quot;color: orange;&quot;&gt;64 bit&lt;/text&gt; process and &lt;text style=&quot;color: orange;&quot;&gt;32 bit&lt;/text&gt; filters. I checked whether a DShow filter works out of the box after rebuilding with &lt;text style=&quot;color: orange;&quot;&gt;64 bit&lt;/text&gt;, and it did. So I had nothing.&lt;br /&gt;
&lt;br /&gt;
Then I had no choice but to run both versions in separate debugger instances simultaneously, stepping to the point where something differed. The debugging was made quite annoying by the fact that for some reason, the &lt;text style=&quot;color: orange;&quot;&gt;32 bit&lt;/text&gt; app would throw an access violation everytime I single stepped, perhaps the environment was broken(I was doing all this over a remote connection), perhaps attaching to a &lt;text style=&quot;color: orange;&quot;&gt;.NET&lt;/text&gt; app calling a &lt;text style=&quot;color: orange;&quot;&gt;C++&lt;/text&gt; dll was messing up the debugger. The only way I could step was to add new breakpoints and resume the execution each time! It finally led to a decryption function, and there was a lot of bit twiddling going on and some typedef&#39;d types. Once again I thought I&#39;d found the issue - I made sure every instance of int in that code was replaced with &lt;text style=&quot;color: orange;&quot;&gt;_int32&lt;/text&gt; so that the code would not be wrong in assuming every int was 32 bits. But the problem still remained.&lt;br /&gt;
&lt;br /&gt;
Once again I did the side-by-side debugging and painstakingly expanded the macros in the crytpo code to compare intermediate values of expressions, and suddenly the light shone through - A macro that returned the last byte of a &lt;text style=&quot;color: orange;&quot;&gt;DWORD&lt;/text&gt; gave different results on &lt;text style=&quot;color: orange;&quot;&gt;x86&lt;/text&gt; and &lt;text style=&quot;color: orange;&quot;&gt;x64&lt;/text&gt;. In other words, the code was using the big-endian version of things - Looking through a few headers, it became obvious. The code comes from a very old C program, written in the 90s : Though it checked for various architectures, it somehow assumed that anything not &lt;text style=&quot;color: orange;&quot;&gt;x86&lt;/text&gt; was a big-endian platform (which may have been true for the platforms it had been intended for) - However this made it also assume that &lt;text style=&quot;color: orange;&quot;&gt;x64&lt;/text&gt; was a big-endian, and so we had our mess-up.&lt;br /&gt;
So in the end it was just a line or two of code actually changed, but who would have &lt;text style=&quot;color: orange;&quot;&gt;&quot;&lt;i&gt;thunk it&lt;/i&gt;&quot;&lt;/text&gt; eh?&lt;br /&gt;
&lt;br /&gt;
&lt;text style=&quot;color: yellow;&quot;&gt;&lt;i&gt;PS : The title of this post is a pun!&lt;/i&gt;&lt;/text&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/5553373902275204562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2012/02/big-end-failure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/5553373902275204562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/5553373902275204562'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2012/02/big-end-failure.html' title='Big end failure'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-5777521189284871558</id><published>2011-12-12T11:28:00.000-08:00</published><updated>2012-02-06T09:00:56.806-08:00</updated><title type='text'>The third circle</title><content type='html'>&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
.post-body { line-height:1.25;}
pc { color: #00FF00; font-style: italic; }
pf { color: #00FF00; }
pi { color: #FF8000; }
pn { color: #00FF00; }
pk { color: #FFFF00; font-weight: bold; }
ps { color: #FF8000; }
txo { color: orange;}
txy { color: yellow;}
.code { font-size: x-large; border-style:solid; border-width:1px; padding:0px; margin:0px; }
.serif {font-family: serif; font-size: large;}
.li { color: orange; margin: 0px; padding: 0px; line-height:1.25;}
.ul {font-family: serif; font-size: large;}
pre { padding:0px; margin:8px;}
.headin { color: yellow; font-size: x-large; font-family: Arial,Helvetica,sans-serif;}
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;div class=&quot;serif&quot;&gt;In my last post, I had mentioned circle drawing algorithms and how I&#39;d rediscovered one after a couple of decades. &quot;Why rasterize circles in this era of GPUs and 3d accelerators?&quot;, the gentle reader may ask...&lt;br /&gt;
Simply because :&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;It&#39;s always fun to re-visit fundamentals.&lt;/li&gt;
&lt;li&gt;One may wish to merely iterate a point over a circular path and a GPU can&#39;t help you there.&lt;/li&gt;
&lt;li&gt;One may have never heard or thought of this method, so it&#39;s fun!&lt;/li&gt;
&lt;/ul&gt;Let&#39;s look at the ways you can draw circles on a raster array.&lt;br /&gt;
&lt;b class=&quot;headin&quot;&gt;&lt;br /&gt;
The first method&lt;br /&gt;
&lt;/b&gt;The math here is the simplest...Which is why it made most sense to me when I was 9 years old.&lt;br /&gt;
A circle has the equation : &lt;txy&gt;&lt;i&gt;x^2 + y^2 = r^2&lt;/i&gt;&lt;/txy&gt; - So, if you iterate x over the range 0 to r, you can solve for y at each x.&lt;br /&gt;
Drawing lines between these points sequentially gives you an arc that&#39;s quarter of a circle. One can then mirror these points about the origin, both vertically and horizontally to get the other three quarters of the pi(e).&lt;br /&gt;
&lt;br /&gt;
Code follows...&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;procedure&lt;/pk&gt; &lt;pi&gt;TForm1.DrawCircle1(cx,&lt;/pi&gt; &lt;pi&gt;cy,&lt;/pi&gt; &lt;pi&gt;r:&lt;/pi&gt; &lt;pi&gt;Integer);&lt;/pi&gt;
&lt;pk&gt;var&lt;/pk&gt;
  &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;y,&lt;/pi&gt; &lt;pi&gt;rSquared&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;Integer;&lt;/pi&gt;
  &lt;pi&gt;oldy,&lt;/pi&gt; &lt;pi&gt;oldx&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;integer;&lt;/pi&gt;
&lt;pk&gt;begin&lt;/pk&gt;
  &lt;pi&gt;PaintBox1.Canvas.MoveTo(cx,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;r);&lt;/pi&gt;
  &lt;pi&gt;rSquared&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;r;&lt;/pi&gt;

  &lt;pi&gt;oldx&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;0&lt;/pn&gt;&lt;ps&gt;;&lt;/ps&gt;
  &lt;pi&gt;oldy&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r;&lt;/pi&gt;

  &lt;pk&gt;for&lt;/pk&gt; &lt;pi&gt;x&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;0&lt;/pn&gt; &lt;pk&gt;to&lt;/pk&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;pk&gt;do&lt;/pk&gt; &lt;pk&gt;with&lt;/pk&gt; &lt;pi&gt;PaintBox1.Canvas&lt;/pi&gt; &lt;pk&gt;do&lt;/pk&gt;
  &lt;pk&gt;begin&lt;/pk&gt;
    &lt;pi&gt;y&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;Round(Sqrt(rSquared&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;ps&gt;(x&lt;/ps&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;x)));&lt;/pi&gt;

    &lt;pi&gt;MoveTo(cx&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;oldx,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;oldy);&lt;/pi&gt;
    &lt;pi&gt;LineTo(cx&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;y);&lt;/pi&gt;

    &lt;pi&gt;MoveTo(cx&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;oldx,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;oldy);&lt;/pi&gt;
    &lt;pi&gt;LineTo(cx&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;y);&lt;/pi&gt;

    &lt;pi&gt;MoveTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;oldx,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;oldy);&lt;/pi&gt;
    &lt;pi&gt;LineTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;y);&lt;/pi&gt;

    &lt;pi&gt;MoveTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;oldx,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;oldy);&lt;/pi&gt;
    &lt;pi&gt;LineTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;cy&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;y);&lt;/pi&gt;

    &lt;pi&gt;oldx&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;x;&lt;/pi&gt;
    &lt;pi&gt;oldy&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;y;&lt;/pi&gt;
  &lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;
&lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
Why &lt;txy&gt;&lt;i&gt;Delphi?&lt;/i&gt;&lt;/txy&gt;&lt;br /&gt;
Because it is based on Object Pascal, the simplest, type safe, statically compiled language that I know of - It has all the low level power of &lt;txo&gt;C&lt;/txo&gt;, and most of the convenient features of OO, decent type safe generics, more akin to &lt;txo&gt;C++&lt;/txo&gt; templates than those of &lt;txo&gt;Java&lt;/txo&gt; or &lt;txo&gt;C#&lt;/txo&gt;, plus a superb IDE and RAD designer. It takes very little time to create fully working native GUI applications with it, which are very easily modified.&lt;br /&gt;
&lt;br /&gt;
The language is verbose, and sometimes it requires a lot more code to do some stuff than in &lt;txo&gt;C++&lt;/txo&gt; - but it is very readable - besides, Wirth is my all time favorite computer science chap, and so I&#39;ve a soft spot for Pascal based languages.&lt;br /&gt;
&lt;br /&gt;
So in the code, we iterate x across the range &lt;txo&gt;0..r&lt;/txo&gt; because we can compute one quarter of the circle, and draw it mirrored across the &lt;txo&gt;X&lt;/txo&gt; and &lt;txo&gt;Y&lt;/txo&gt; axes.&lt;br /&gt;
&lt;br /&gt;
Actually we can even compute just 1/8th of the circle and generate the other 7 sections by using all combinations of mirroring and swapping X and Y values.&lt;br /&gt;
&lt;br /&gt;
Note that since we iterate over &lt;txo&gt;X&lt;/txo&gt; linearly, The exact shape drawn is not a perfect circle - At the points where &lt;txo&gt;Y&lt;/txo&gt; gets incremented a lot of a change of &lt;txo&gt;1&lt;/txo&gt; in &lt;txo&gt;X&lt;/txo&gt;, there are quite straight lines. Doing it by mirroring four or eight pieces does it much better, since a quarter or eighth of &lt;txo&gt;90&lt;/txo&gt; degrees is not a big angle and the maximum &lt;txo&gt;dx/dy&lt;/txo&gt; for that range is less than &lt;txo&gt;1&lt;/txo&gt;&lt;br /&gt;
&lt;b class=&quot;headin&quot;&gt;&lt;br /&gt;
Method 2&lt;br /&gt;
&lt;/b&gt;I know, all you academic minded ones were dying to read this one.&lt;br /&gt;
&lt;txy&gt;&lt;i&gt;x = r cos Q and y = r sin Q&lt;/i&gt;&lt;/txy&gt;&lt;br /&gt;
&lt;br /&gt;
Not much to say about this - When I first learned of sines and cosines, I was like - &lt;txy&gt;&lt;i&gt;&quot;Ah OK, it&#39;s just a look-up table of magic values for the ratios of x and y with h for every angle&quot;&lt;/i&gt;&lt;/txy&gt; - And for the most part it is....&lt;br /&gt;
Inside your FPU is a lookup table and some interpolation magic to give you &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;procedure&lt;/pk&gt; &lt;pi&gt;TForm1.DrawCircle2(cx,&lt;/pi&gt; &lt;pi&gt;cy,&lt;/pi&gt; &lt;pi&gt;r:&lt;/pi&gt; &lt;pi&gt;Integer);&lt;/pi&gt;
&lt;pk&gt;var&lt;/pk&gt;
  &lt;pi&gt;angle,&lt;/pi&gt; &lt;pi&gt;angleInc,&lt;/pi&gt; &lt;pi&gt;angleMax&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;Extended;&lt;/pi&gt;
  &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;y&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;Extended;&lt;/pi&gt;
&lt;pk&gt;begin&lt;/pk&gt;
  &lt;pi&gt;PaintBox1.Canvas.MoveTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;r,&lt;/pi&gt; &lt;pi&gt;cy);&lt;/pi&gt;

  &lt;pi&gt;angleinc&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;1&lt;/pn&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;pi&gt;r;&lt;/pi&gt;
  &lt;pi&gt;angle&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;0&lt;/pn&gt;&lt;ps&gt;;&lt;/ps&gt;
  &lt;pi&gt;angleMax&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;ps&gt;(&lt;/ps&gt;&lt;pn&gt;2&lt;/pn&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pf&gt;3.14159265&lt;/pf&gt;&lt;ps&gt;)&lt;/ps&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;angleinc;&lt;/pi&gt;

  &lt;pk&gt;while&lt;/pk&gt; &lt;pi&gt;angle&lt;/pi&gt; &lt;ps&gt;&amp;lt;=&lt;/ps&gt; &lt;pi&gt;angleMax&lt;/pi&gt; &lt;pk&gt;do&lt;/pk&gt;
  &lt;pk&gt;begin&lt;/pk&gt;
    &lt;pi&gt;x&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;Cos(angle);&lt;/pi&gt;
    &lt;pi&gt;y&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;Sin(angle);&lt;/pi&gt;
    &lt;pi&gt;PaintBox1.Canvas.LineTo(Round(x)&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;cx,&lt;/pi&gt; &lt;pi&gt;Round(y)&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;cy);&lt;/pi&gt;
    &lt;pi&gt;angle&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;angle&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;angleinc;&lt;/pi&gt;
  &lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;
&lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
We iterate over the &lt;txo&gt;360&lt;/txo&gt; degrees, but we do not choose an arbitrary increment. Too small an increment and we redraw the same pixel, too big and our circle becomes a polygon.&lt;br /&gt;
&lt;br /&gt;
Since the perimeter of a circle is &lt;txy&gt;&lt;i&gt;2 * PI * r&lt;/i&gt;&lt;/txy&gt; and we want that many pixels drawn at most and at least, the angle we increment by is &lt;txy&gt;&lt;i&gt;(2 * PI) / (2 * PI * r)&lt;/i&gt;&lt;/txy&gt; which is &lt;txy&gt;&lt;i&gt;1/r&lt;/i&gt;&lt;/txy&gt;&lt;br /&gt;
&lt;br /&gt;
This means the target pixel drawn at each iteration is one pixel distance away from the last one. This will certainly result in some overdraw, but it is a reasonable value to use. Any more and we will get gaps where the small line segments that form our circle are parallel to the &lt;txo&gt;X&lt;/txo&gt; and &lt;txo&gt;Y&lt;/txo&gt; axes.&lt;br /&gt;
&lt;b class=&quot;headin&quot;&gt;&lt;br /&gt;
Method 3&lt;br /&gt;
&lt;/b&gt;This is a surprisingly ingenious way to avoid trigonometric functions in the loop. Back in the old days, such operations were really heavy, and I dare say this method would have been the fastest. In my test code, it just about beats the second method, but the margin is too small to be of much significance. The reason is that in this day and age, &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt; are not so expensive after all, they are probably single cycle instructions on all current processors.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;pk&gt;procedure&lt;/pk&gt; &lt;pi&gt;TForm1.DrawCircle3(cx,&lt;/pi&gt; &lt;pi&gt;cy,&lt;/pi&gt; &lt;pi&gt;r:&lt;/pi&gt; &lt;pi&gt;Integer);&lt;/pi&gt;
&lt;pk&gt;var&lt;/pk&gt;
  &lt;pi&gt;angle,&lt;/pi&gt; &lt;pi&gt;angleInc&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;Extended;&lt;/pi&gt;
  &lt;pi&gt;i&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;integer;&lt;/pi&gt;
  &lt;pi&gt;x,&lt;/pi&gt; &lt;pi&gt;y,&lt;/pi&gt; &lt;pi&gt;sina,&lt;/pi&gt; &lt;pi&gt;sinb,&lt;/pi&gt; &lt;pi&gt;cosa,&lt;/pi&gt; &lt;pi&gt;cosb,&lt;/pi&gt; &lt;pi&gt;sinab,&lt;/pi&gt; &lt;pi&gt;cosab&lt;/pi&gt; &lt;ps&gt;:&lt;/ps&gt; &lt;pi&gt;Extended;&lt;/pi&gt;
&lt;pk&gt;begin&lt;/pk&gt;
  &lt;pi&gt;PaintBox1.Canvas.MoveTo(cx&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;r,&lt;/pi&gt; &lt;pi&gt;cy);&lt;/pi&gt;

  &lt;pi&gt;angleinc&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;360&lt;/pn&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;pi&gt;r;&lt;/pi&gt;
  &lt;pi&gt;sinb&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;Sin(angleinc&lt;/pi&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;ps&gt;(&lt;/ps&gt;&lt;pf&gt;180.0&lt;/pf&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;pf&gt;3.14159&lt;/pf&gt;&lt;ps&gt;));&lt;/ps&gt;
  &lt;pi&gt;cosb&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;Cos(angleinc&lt;/pi&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;ps&gt;(&lt;/ps&gt;&lt;pf&gt;180.0&lt;/pf&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;pf&gt;3.14159&lt;/pf&gt;&lt;ps&gt;));&lt;/ps&gt;

  &lt;pi&gt;sina&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;0&lt;/pn&gt;&lt;ps&gt;;&lt;/ps&gt;
  &lt;pi&gt;cosa&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pn&gt;1&lt;/pn&gt;&lt;ps&gt;;&lt;/ps&gt;

  &lt;pi&gt;i&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;Round(&lt;/pi&gt;&lt;pn&gt;360&lt;/pn&gt; &lt;ps&gt;/&lt;/ps&gt; &lt;pi&gt;angleinc);&lt;/pi&gt;
  &lt;pk&gt;while&lt;/pk&gt; &lt;pi&gt;i&lt;/pi&gt; &lt;ps&gt;&amp;gt;&lt;/ps&gt; &lt;pn&gt;0&lt;/pn&gt; &lt;pk&gt;do&lt;/pk&gt;
  &lt;pk&gt;begin&lt;/pk&gt;
    &lt;pi&gt;sinab&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;sina&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;cosb&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;cosa&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;sinb;&lt;/pi&gt;
    &lt;pi&gt;cosab&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;cosa&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;cosb&lt;/pi&gt; &lt;ps&gt;-&lt;/ps&gt; &lt;pi&gt;sina&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;sinb;&lt;/pi&gt;
    &lt;pi&gt;x&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;cosab;&lt;/pi&gt;
    &lt;pi&gt;y&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;r&lt;/pi&gt; &lt;ps&gt;*&lt;/ps&gt; &lt;pi&gt;sinab;&lt;/pi&gt;
    &lt;pi&gt;sina&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;sinab;&lt;/pi&gt;
    &lt;pi&gt;cosa&lt;/pi&gt; &lt;ps&gt;:=&lt;/ps&gt; &lt;pi&gt;cosab;&lt;/pi&gt;
    &lt;pi&gt;Dec(i);&lt;/pi&gt;
    &lt;pi&gt;PaintBox1.Canvas.LineTo(Round(x)&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;cx,&lt;/pi&gt; &lt;pi&gt;Round(y)&lt;/pi&gt; &lt;ps&gt;+&lt;/ps&gt; &lt;pi&gt;cy);&lt;/pi&gt;
  &lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;
&lt;pk&gt;end&lt;/pk&gt;&lt;ps&gt;;&lt;/ps&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
Once again, we use the sine and cosine relations while iterating over all the angles, however, a simple trigonometric identity lets us avoid calling &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt; more than once.&lt;txy&gt;&lt;i&gt;&lt;br /&gt;
sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b) &lt;br /&gt;
cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)&lt;br /&gt;
&lt;/i&gt;&lt;/txy&gt;If &lt;txo&gt;A&lt;/txo&gt; be our initial angle namely &lt;txo&gt;0&lt;/txo&gt;, and &lt;txo&gt;B&lt;/txo&gt; be the increment, we can get &lt;txo&gt;sin(A + B)&lt;/txo&gt; and &lt;txo&gt;cos(A + B)&lt;/txo&gt; quite simply. After that A gets the new incremented angle and we can repeat the process.&lt;br /&gt;
&lt;br /&gt;
We ended up replacing the &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt; function calls with four multiplications and an addition and a subtraction.&lt;br /&gt;
&lt;br /&gt;
In a static compiled or &lt;txo&gt;JIT&lt;/txo&gt; compiled language &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt; go down as single FPU instructions, and this doesn&#39;t make much of a difference in speed - However, in an interpreted language, I believe a function call will occur, and might end up being hundreds of times more expensive than the arithmetic.&lt;br /&gt;
&lt;br /&gt;
It might even be possible to write this code using integer arithmetic alone, which you can&#39;t do with &lt;txo&gt;sin()&lt;/txo&gt; and &lt;txo&gt;cos()&lt;/txo&gt; - This may be useful in some embedded systems.&lt;br /&gt;
&lt;br /&gt;
There is something quite similar (or is it exactly same?) on &lt;a href=&quot;http://www.inwap.com/pdp10/hbaker/hakmem/hacks.html#item149&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;&lt;txo&gt;&lt;/txo&gt;HAKMEM item 149 to 152&lt;/txo&gt;&lt;/u&gt;&lt;/a&gt;, but that doesn&#39;t give a universal circle drawing algorithm.&lt;br /&gt;
&lt;br /&gt;
One thing to bear in mind is that errors might get accumulated in this method, since it is incremental in nature, but we&#39;re working with integer co-ordinate output, so I doubt if you would get enough error to plot an incorrect pixel.&lt;br /&gt;
&lt;br /&gt;
&lt;txy&gt;So that was the mystery of the third circle!&lt;/txy&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/5777521189284871558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2011/12/third-circle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/5777521189284871558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/5777521189284871558'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2011/12/third-circle.html' title='The third circle'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-1793174181636804343</id><published>2011-12-10T03:13:00.001-08:00</published><updated>2012-02-04T10:01:53.987-08:00</updated><title type='text'>Perspective correct texture mapping</title><content type='html'>&lt;div style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;  &lt;p&gt;    Recently I worked on an interesting project, which involved creating rudimentary 3d rendering on a 2d HTML5 canvas using javascript.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Why not WebGL or CSS 3d transforms?&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Because this was meant to run on some smart phones that did not support those in their browsers. The client required a way to display an image rotated in 3d space, with perspective projection. Now, while the canvas object supports 2d transformations like rotation, scaling and shearing, it is not possible to do perspective projection using these alone, so a from scratch implementation was needed.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Considering that it had to be coded in javascript, the implementation had to be as fast as possible so that it could be used for real time animation effects.&lt;br /&gt;
  &lt;/p&gt;  &lt;p style=&quot;color: yellow; font-size: x-large;&quot;&gt;    &lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;How it&#39;s done&lt;/b&gt;&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    The first thing to do was to create a representation of a 3d co-ordinate, that could be rotated, scaled and translated in any dimension.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Now I&#39;m not a big fan of plugging in formulas into code directly, so I usually rework the math from scratch every time. I opted not to use the so called simple approach of homogenous transformation matrices, since (at least to me), the real meaning of what happens to a 3d point when transformed gets obscured in the matrix. Instead I chose a more direct approach. When we consider a 3d rotation, we see that it can be represented by rotation along two axes.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    I opted to use the intuitive representation of yaw and pitch - Imagine a sphere like the earth with a point on it - Yaw makes the point orbit along its latitude, while pitch moves it along its longitude.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    After some scribbled diagrams, a little sine here and a little cosine there, I got the rotation math right. Translation and scaling are very simply addition and multiplication of the co ordinate values by some factor.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    While coding this, I realized one long forgotten trick - About two decades ago, I remember a book I read titled &lt;b style=&quot;color: yellow;&quot;&gt;Electron Graphics and Sound&lt;/b&gt; which first taught me the fundamentals of computer graphics.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Now the Electron microcomputer, and its more advanced cousin the BBC micro were 8 bit machines from the early 80s and ran at 1 Mhz with 32KB of RAM. In the book, the author detailed three methods of drawing circles, each faster than the previous.&lt;br /&gt;
  &lt;/p&gt;  The first two were quite simple : &lt;i&gt;&lt;br /&gt;
    &lt;ul&gt;      &lt;li style=&quot;color: orange;&quot;&gt;Solve Y for every X, given R and the Pythagoras theorem.&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;Use X = R cos(theta) and Y = R sin(theta)&lt;/li&gt;
    &lt;/ul&gt;  &lt;/i&gt;Both these approaches were very slow, because square-roots and trigonometric operations were very expensive on these machines.&lt;br /&gt;
  &lt;p&gt;    The third method calculated a sine and cosine only once outside the loop, and had nothing but arithmetic inside the loop. It was blazing fast. I never fully understood how that worked back then, but knew that there was something to it. For years afterwards I tried to remember what the code was meant to do, but I could not, and I didn&#39;t have the book anymore.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Now suddenly, while I was implementing the rotation code for this 3d stuff, it dawned on me, and I rediscovered the third algorithm finally. I&#39;ll detail that in the next post.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    So now that I had the 3d co-ordinates representation worked out, I created an abstraction for an image floating around in 3d space, with each of its corners represented as a 3d point. The next step is...&lt;br /&gt;
  &lt;/p&gt;  &lt;p style=&quot;color: yellow; font-size: x-large;&quot;&gt;    &lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;2d Projection&lt;/b&gt;&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    We need to map those image edge points onto the 2d screen, correcting for perspective. This is quite a simple operation...&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    In most 3d scenes represented on a 2d view, there is a vanishing point and as things get further away, they get closer to the vanishing point. At infinite distance, all 3d points map onto the vanishing point. So it&#39;s a simple matter of moving the X and Y co-ordinates towards the vanishing point based on the Z.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    You need to choose some projection parameters such as the view angle/scale, how many pixels represents one unit of space along the Z axis, and where along the Z axis the observers eye is located. If we call the unit zunit, the scale factor zscale and the eye position zeye then : &lt;i style=&quot;color: yellow;&quot;&gt;The object appears zscale times smaller for every zunit away from zeye ...&lt;/i&gt;&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    That sounds very German when spoken out loud but it&#39;s English! Now we end up with a trapezoid that represents how the image edges would look in 3d space, when drawn on the 2d screen. Next we move on to...&lt;br /&gt;
  &lt;/p&gt;  &lt;p style=&quot;color: yellow; font-size: x-large;&quot;&gt;    &lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;Texture mapping&lt;/b&gt;&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    We need to map the image texture from its original rectangular shape onto the projected trapezoid. The naive way to do this would be : &lt;i&gt;&lt;br /&gt;
      &lt;ul style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;        &lt;li style=&quot;color: orange;&quot;&gt;Loop over every image co-ordinate&lt;/li&gt;
        &lt;li style=&quot;color: orange;&quot;&gt;Transform the point according to the current pitch/yaw/scale&lt;/li&gt;
        &lt;li style=&quot;color: orange;&quot;&gt;Project the point onto 2d&lt;/li&gt;
        &lt;li style=&quot;color: orange;&quot;&gt;Draw that pixel with the image pixel&lt;/li&gt;
      &lt;/ul&gt;    &lt;/i&gt;&lt;br /&gt;
    This would be embarrassingly slow and moreover it would also be wrong! First of all, doing several trigonometric ops per pixel will defenestrate performance completely and secondly this assumes that every single source pixel on the image rectangle maps to a single pixel on the destination - which is wrong.&lt;br /&gt;
  &lt;p&gt;  &lt;/p&gt;  An image pixel can actually map to any number of pixels on the trapezoid, since a region of the trapezoid can be bigger or smaller than the corresponding region on the image. Thus, we need to use the well established technique of doing mappings in reverse - the logic is as follows : &lt;i&gt;&lt;br /&gt;
    &lt;ul style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;      &lt;li style=&quot;color: orange;&quot;&gt;We need to draw every pixel on the destination trapezoid&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;We need to draw each pixel once and only once!&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;Thus we should iterate over the destination pixels, find the corresponding source point on the image, and then paint that on&lt;/li&gt;
    &lt;/ul&gt;  &lt;/i&gt;OK that deals with one of the problems, above but what about performance? First of all, how do we iterate over all the pixels on the quad? The fast way to do this is to always is scan-line by scan-line, which ensures that memory access is as linear as possible when we access the pixel data. So the first step is to find out the vertical span of the trapezoid - which is nothing but the minimum and maximum Y of all of the four corners. Now we iterate over the Y span and figure out the X span at each Y thusly:&lt;br /&gt;
&lt;br /&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_TFjxjiQAOXl4-jKKn7BHePFJ0SJZqBkeaC-Mhqf_nZ36tvvWCH71dcgMSn9vmgnsWXXHp-taYFfyAxhtqJf2sg5RT1PAHIT4MnC3uPl5LxcScqNAEFiNKNLISJefGV20i21IfMsox_U/s1600/quad.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
      &lt;img border=&quot;0&quot; height=&quot;559&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_TFjxjiQAOXl4-jKKn7BHePFJ0SJZqBkeaC-Mhqf_nZ36tvvWCH71dcgMSn9vmgnsWXXHp-taYFfyAxhtqJf2sg5RT1PAHIT4MnC3uPl5LxcScqNAEFiNKNLISJefGV20i21IfMsox_U/s640/quad.png&quot; width=&quot;640&quot; /&gt;&lt;br /&gt;
    &lt;/a&gt;&lt;br /&gt;
  &lt;/div&gt;&lt;br /&gt;
  Now that we have a Y and a range of X to draw on the destination, we need to find which point on the image maps here.&lt;br /&gt;
  &lt;p&gt;    Say we are on point P on the red scan-line... we are a fraction PR/RS along the line RS. R is a fraction AR/AB along line AB and S is a fraction AS/AC along line AC. We could find out where P would end up on the source image using the same relation, interpolating linearly, and using the image vertices for A, B and C. This ought to be the pixel that&#39;s drawn at P on the trapezoid...&lt;br /&gt;
  &lt;/p&gt;  Elementary... Or so I thought!&lt;br /&gt;
  &lt;p&gt;  &lt;/p&gt;  Except that things are not so linear - The results looked good on photographic images, but when I used a grid image as a test, the output looked extremely warped when the perspective was high. There was some curvature induced on horizontal lines like this :&lt;br /&gt;
&lt;br /&gt;
  &lt;div style=&quot;clear: both; text-align: center;&quot;&gt;    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNwW-4in-fa6GBE8dQ3KMoh8It9H645D7nr1j9GmjP1WyPVrLyHlukwwnrgcBUEeA4IwMGo62K3SqprdZEUs5sP3cis5wQyuACz_vXuvzvfaf_w4AA5qMnGmn2hJNzaJPqRrhaKcyP-kk/s1600/warp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
      &lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNwW-4in-fa6GBE8dQ3KMoh8It9H645D7nr1j9GmjP1WyPVrLyHlukwwnrgcBUEeA4IwMGo62K3SqprdZEUs5sP3cis5wQyuACz_vXuvzvfaf_w4AA5qMnGmn2hJNzaJPqRrhaKcyP-kk/s640/warp.png&quot; width=&quot;368&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
  Looks somewhat like relativistic contraction effects! But we&#39;re supposed to be stationary! This approach was super-fast - It was down to about 13ms for rendering a 800x600 image on Chrome.&lt;br /&gt;
  &lt;p&gt;    There were only about 8 arithmetic operations in the inner loop. The warping is quite undetectable on photographic images, but still, it&#39;s wrong!&lt;/p&gt;  &lt;p style=&quot;color: yellow; font-size: x-large;&quot;&gt;    &lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;The right way&lt;/b&gt;&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;  &lt;/p&gt;  So I decided to rework the math to solve the following problem :&lt;br /&gt;
&lt;br /&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_or1e5cGJriE2yr71QnTUTyrdAfdGOqZvHCIsCGQlSad6jQm9ljABUuoPKozGEX2wGyyLIIY_46Znqfg3Ajl3c4NWC2H9CyJnvT_shnIOYXM8u5cm7Y6LnXJllvaUJcl7VBDDznznK0/s1600/quadprob.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
      &lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_or1e5cGJriE2yr71QnTUTyrdAfdGOqZvHCIsCGQlSad6jQm9ljABUuoPKozGEX2wGyyLIIY_46Znqfg3Ajl3c4NWC2H9CyJnvT_shnIOYXM8u5cm7Y6LnXJllvaUJcl7VBDDznznK0/s640/quadprob.png&quot; width=&quot;480&quot; /&gt;&lt;br /&gt;
    &lt;/a&gt;&lt;br /&gt;
  &lt;/div&gt;&lt;br /&gt;
  Once we had f1 and f2, we could look up the same point on the image rectangle easily. I started out on paper, wrote the equations for f1 and f2, and filled several sheets, getting nowhere.&lt;br /&gt;
  &lt;p&gt;    I started again, this time using a text editor, so I could avoid mistakes when substituting expressions. I also wrote a C program to assert the validity of each step of the equation as I progressed, using actual values, and this helped me catch some errors I had made. This seems like a good way to do algebra, since later on, you can simply copy and paste the code into your program!&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    I won&#39;t bore you with the algebra, since it&#39;s quite involved... but finally I ended up with a quadratic equation, that could be solved for f1, and f2 could be derived easily from f1.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Now, I knew this was going to be quite slow! Solving a quadratic for every pixel is heavy, since there is a square root involved, and besides the co-efficients were complex expressions involving many of the input co-ordinates and distances. More variables accessed in the inner loop always means more code-sloth. I tested it out and the rendering was perfect, but the performance abysmal. That needed fixing.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    Then I recalled my client had mentioned something about implementing Quake style optimizations, since it had been mentioned in a web page that demonstrated perspective texture mapping in C. After looking it up, I realized quite soon what the idea was (vaguely remember reading about this in &lt;b style=&quot;color: yellow;&quot;&gt;Michael Abrash&#39;s &lt;i&gt;Black Book Of Graphics Programming&lt;/i&gt;). &lt;/b&gt;&lt;br /&gt;
    &lt;p&gt;      In a nutshell, instead of doing the mapping math on every pixel, do it every N pixels and in between use linear interpolation for the texture co-ordinates. Over a small region such as 16x16, the error is not visible, so it&#39;s a great compromise between speed and accuracy. The funny thing is that if we increase the step from N to say, the entire X span width, we end up with exactly the original incorrect warped output!&lt;br /&gt;
    &lt;/p&gt;  &lt;p&gt;    Then I did a few vanilla optimizations - loop hoisting, making the texture image&#39;s width padded to a power of two (a simple trick to make i = y * w + x into i = y &amp;lt;&amp;lt; n + x while accessing the canvas data buffer), and reducing variable access in the inner loop. After implementing all this, the performance ended up at about 60ms per frame to render a 800x600 image texture. In a pinch, the step N can be increased to about 64 to double performance and it still looks good.&lt;br /&gt;
  &lt;/p&gt;  So there you have it! Quite amazing that we can do this stuff in real time in Javascript.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/1793174181636804343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2011/12/perspective-correct-texture-mapping.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/1793174181636804343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/1793174181636804343'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2011/12/perspective-correct-texture-mapping.html' title='Perspective correct texture mapping'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_TFjxjiQAOXl4-jKKn7BHePFJ0SJZqBkeaC-Mhqf_nZ36tvvWCH71dcgMSn9vmgnsWXXHp-taYFfyAxhtqJf2sg5RT1PAHIT4MnC3uPl5LxcScqNAEFiNKNLISJefGV20i21IfMsox_U/s72-c/quad.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-4626078591684163628</id><published>2011-12-05T07:40:00.001-08:00</published><updated>2012-02-04T10:30:20.085-08:00</updated><title type='text'>Reinventing the wheel for fun and profit</title><content type='html'>&lt;div style=&quot;font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; font-size: large;&quot;&gt;  A few months back, I had been involved in an image processing project, which dealt with image binarization for OCR. One of the steps during that process was to segment an image into regions labeled red, white and black. They represented black on white text, white on black text and blank regions respectively. The input consisted of three monochrome images with non regular regions filled with white. The segmentation was done as follows: &lt;i&gt;&lt;br /&gt;
    &lt;ul&gt;      &lt;li style=&quot;color: orange;&quot;&gt;A rectangle is chosen (initially the entire image), and for both vertical and horizontal directions, at every possible location to split was tested.&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;At each split point, the pixel counts for the two sub rectangles were taken for each of the three input images.&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;The split point was assigned a score based on how uniform the two sub rectangles were in terms of the labeled pixels.&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;The best split point was chosen and we now had two rectangles.&lt;/li&gt;
      &lt;li style=&quot;color: orange;&quot;&gt;The process repeated recursively for both these rectangles, until they reached a certain score, or a certain minimum size.&lt;/li&gt;
    &lt;/ul&gt;  &lt;/i&gt;Suffice to say that most of the work involved counting the number of “on” pixels in an arbitrary rectangular region of an image. Here is a visualization of how the splitting ends up for a web page image – The regions that are predominantly white on black are green, those that are black on white are marked red and the split lines are blue.&lt;br /&gt;
&lt;br /&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl9cUxXwSs80KL6eQtr2pv40zs6NSFZY56Gu8iNqD7XYj8cAYKCbcl4tZyYHFbFnqHu-u0B3rxd8Aul8Dqt2tXBq3t7Rd1sd3ydFTLJvlz5hsbFbQOFEUtF_Ak9NeuegQ1ohmK46QMSAM/s1600/split.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
      &lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl9cUxXwSs80KL6eQtr2pv40zs6NSFZY56Gu8iNqD7XYj8cAYKCbcl4tZyYHFbFnqHu-u0B3rxd8Aul8Dqt2tXBq3t7Rd1sd3ydFTLJvlz5hsbFbQOFEUtF_Ak9NeuegQ1ohmK46QMSAM/s1600/split.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
  After I got the initial implementation working, it was horrendously slow, because for every rectangle, at every horizontal or vertical split position, the number of “on” pixels was counted by iterating entirely over the two split rectangles The first optimization that came to mind was to initially do the count for the whole rectangle and maintain the pixel count at every split line too. The pixel counts for both sides could then be incrementally calculated, as the split point moved across the rectangle. However, this process would have to be repeated for the sub rectangles, so it would still be slow. I scratched my head for about a minute and then suddenly I had it – If we could calculate and cache the counts for every possible rectangle starting at (0, 0) then we could get the count for any arbitrary rectangle with a handful of arithmetic ops – thusly :&lt;br /&gt;
&lt;br /&gt;
  &lt;div class=&quot;separator&quot; style=&quot;background-color: black; clear: both; color: lime; font-family: Georgia,&amp;quot; times new roman&amp;quot; ,serif; text-align: center;&quot;&gt;    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggpu7xaj7UVD_i2Mpui5vAHMkTq-kI_S-hmoGE4Kry8FnBQd4PQnBNwQjkEZbWt7yjsxaHgwDEWXoQH3Fgva6lLxsHwXCU9tNpXWV4-PZR2GFXirWRZyT98J8ATRWwwU8pTFDhJl57XGA/s1600/iintimg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
      &lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggpu7xaj7UVD_i2Mpui5vAHMkTq-kI_S-hmoGE4Kry8FnBQd4PQnBNwQjkEZbWt7yjsxaHgwDEWXoQH3Fgva6lLxsHwXCU9tNpXWV4-PZR2GFXirWRZyT98J8ATRWwwU8pTFDhJl57XGA/s1600/iintimg.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
  &lt;/div&gt;&lt;br /&gt;
  To get the count for the green rectangle K, we take the sum of the entire image up to the bottom right corner of K and from that we subtract the top region and the left region. We ended up subtracting the purple top-left region twice, so we add it back once. All these rectangles start at (0, 0) can be read directly from our precomputed cache.So in essence for any rectangle in the image, we can get the pixel count by doing 4 memory accesses and three subtractions.&lt;br /&gt;
  &lt;p&gt;  &lt;/p&gt;  Blazing fast! So fast in fact, that this becomes the fastest part of the whole algorithm.&lt;br /&gt;
  &lt;p&gt;    After a few days, I find out that this technique is a known one called by the fancy name “integral images”, and can be used in a number of applications where arrays of any number of dimensions have to be summed up.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    I&#39;m thinking of implementing a 2D LZ77 like compression technique based on this that would be suitable for screen-shot like images. The idea would be to quickly identify two equal sized rectangular regions that sum up to the same value. Two patches that had the same sum would be a potential match. Differing sums would mean the patches could never match exactly, so we avoid a lot of pixel-wise comparison. That means we can test every possible rectangle against every other one to find matches, and do it quite fast.&lt;br /&gt;
  &lt;/p&gt;  &lt;p&gt;    What was a bit funny to me was that this technique seems so obvious (as I said before, it took me all of a minute to come up with this and realize it would work), but has a pretty fancy name and was one of the key “innovations” of the famous Viola-Jones face detection paper, which convinces me further of how academic literature tends to make quite simple stuff seem complex and path-breaking.&lt;br /&gt;
  &lt;/p&gt;  &lt;b&gt;&lt;br /&gt;
    &lt;p style=&quot;color: yellow;&quot;&gt;      Moral of the story:&lt;br /&gt;
    &lt;/p&gt;  &lt;/b&gt;&lt;i style=&quot;color: orange;&quot;&gt;Invent as many wheels as you can - many of them will be re-inventions, but the process of invention is more fun and beneficial than that of using a pre-invented wheel.&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/4626078591684163628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2011/12/reinventing-wheel-for-fun-and-profit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4626078591684163628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/4626078591684163628'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2011/12/reinventing-wheel-for-fun-and-profit.html' title='Reinventing the wheel for fun and profit'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl9cUxXwSs80KL6eQtr2pv40zs6NSFZY56Gu8iNqD7XYj8cAYKCbcl4tZyYHFbFnqHu-u0B3rxd8Aul8Dqt2tXBq3t7Rd1sd3ydFTLJvlz5hsbFbQOFEUtF_Ak9NeuegQ1ohmK46QMSAM/s72-c/split.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5338845766123238061.post-6363958159727217573</id><published>2011-12-03T09:57:00.001-08:00</published><updated>2012-02-04T05:46:27.164-08:00</updated><title type='text'>Overdue optimization is the root of all bloat</title><content type='html'>&lt;div style=&quot;background-color: black; color: lime; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;i style=&quot;color: yellow;&quot;&gt;&quot;Premature optimization is the root of all evil&quot;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: black; color: lime; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;It&#39;s an oft-repeated mantra among people in the industry – everybody rightly presumes that slow working code is better than fast broken code.&lt;br /&gt;&lt;br /&gt;However this is based on the dubious assumption that a given programmers code is bound to be less ridden with bugs if he codes a slow approach. And the further weak premise that code is ever fully correct. &lt;br /&gt;&lt;br /&gt;Let&#39;s look at another industry, the automotive one – Any serious vehicle is designed with a certain performance metric from the start, and unless it meets that, it is a failure. In the software world, fast code is often seen as complex code, but that is a very naive view of optimization. A true optimization, in theory, reduces the amount of work being done, and often the amount of code. Any complexity induced is more of a syntactic nature, depending on the expressive skill of the programmer.&lt;br /&gt;&lt;br /&gt;Compilers are damn smart these days, but then again things haven&#39;t really changed that much – Take a look at the following code that copies C style NUL terminated strings.&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: black; color: lime; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;int j = 0;&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(src[j])&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dst[j] = src[j];&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++j;&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br /&gt;Then this :&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: black; color: lime; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: orange;&quot;&gt;char *pSrc = src, *pDst = dst;&lt;/span&gt;&lt;/span&gt;&lt;br style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(*pDst++ = *pSrc++);&lt;/span&gt;&lt;br style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br /&gt;The second version is full 6% faster measured over a million iterations for 64KB strings, compiled with MSVC 2010, all optimizations on.&lt;br /&gt;&lt;br /&gt;One would assume that the compiler is capable of generating the same code for both, but in the first case it reloads the value for src[j] in order to check it for NUL in the while loop. In the second version,&amp;nbsp; --which generates the exact same code as an inline call to &lt;span style=&quot;color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;strcpy()&lt;/span&gt; --, one memory access is avoided.&lt;br /&gt;&lt;br /&gt;6% is not an insignificant fraction, for a trivial optimization like this.&lt;br /&gt;&lt;br /&gt;Of course, this is a contrived example, but the same principles hold in a number of scenarios.&lt;br /&gt;&lt;br /&gt;Some would argue that the second version is less readable. I would counter that it indicates a lack of fluency in the language involved.&lt;br /&gt;Any non-trivial piece of code requires a certain amount of programming skill, and in most cases, someone who is qualified enough to write a correct implementation is capable of writing a correct and fast version too.&lt;br /&gt;&lt;br /&gt;If someone makes errors during optimization, that is essentially carelessness that would have happened even while writing a vanilla implementation. Sloppy coding won&#39;t be cured by using naive approaches.&lt;br /&gt;&lt;br /&gt;Starting out with the intent that code must be fast as well as correct, one must gather good habits and make it almost reflex like to perform small optimizations and diligently work to understand fast ways of doing common tasks. You don&#39;t become a boxer by first concentrating on accuracy, then strength, then speed – You do all three at once. An awareness of what is happening behind the scenes in the generated machine code is very important; not only for speed optimization, but also for figuring out what is wrong when things go south. This applies to even non-compiled languages – Understanding how memory is organized and how data structures end up on the metal leads to good coding approaches.&lt;br /&gt;&lt;br /&gt;Dumbing down the code initially will most probably lock it down in such a fashion that reworking it to be faster at a higher level will become impractically difficult, and doing low level optimizations later, may not be of much value.&lt;br /&gt;&lt;br /&gt;It&#39;s the difference between a super car built ground up for performance versus a clunker with bolt on supercharging.&lt;br /&gt;&lt;br /&gt;There is a lot of running code out there, almost all of it is buggy, but very little is efficient – Bloat abounds, since hardware cost goes down and performance goes up regularly. However, the brick wall is near, since improving serial code execution speeds has become more and more difficult. The only way out is parallelism, and that is being marketed aggressively; the only problem is that no one got the memo on the inapplicability of parallelism for most code.&lt;br /&gt;&lt;br /&gt;You can have a zillion cores and parallelize all the possible parts of your program, but the serial path will remain, and the only choice is to go back to school and read some &lt;b style=&quot;color: orange;&quot;&gt;Michael Abrash&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: yellow; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;TANSTAFC - &lt;/span&gt;&lt;i style=&quot;color: yellow;&quot;&gt;There ain&#39;t no such thing as the fastest code&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schmantics.blogspot.com/feeds/6363958159727217573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://schmantics.blogspot.com/2011/12/overdue-optimization-is-root-of-all.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/6363958159727217573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5338845766123238061/posts/default/6363958159727217573'/><link rel='alternate' type='text/html' href='http://schmantics.blogspot.com/2011/12/overdue-optimization-is-root-of-all.html' title='Overdue optimization is the root of all bloat'/><author><name>rep_movsd</name><uri>http://www.blogger.com/profile/13340953911780739648</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>