Monthly Archives: March 2021

Simple Loops in JavaScript

I let SonarQube inspect my JavaScript code and it had opinions about my loops. I learnt about the for-of-loop. Let us see what we have.

Below four loop-constructions are for most practical purposes the same.

  // good old for-loop
  for ( let i=0 ; i<array.length ; i++ ) {
    const x = array[i];
    ...
  }

  // for-in-loop
  for ( const i in array ) {
    const x = array[i];
    ...
  }

  // for-of-loop
  for ( const x of array ) {
    ...
  }

  // forEach
  array.forEach((x) => {
     ...
  });

Well, if they are all practially the same, why bother? Why not pick one for all cases? Well, in the details, they are different when it comes to

  • simplicity to write / verboseness
  • performance
  • flexibility and explicitness

Lets discuss the loops.

The good old for-loop

The good old for-loop requires you to write the name of the array twice, and you need to explicitely increment the loop variable and compare it the length of the array. This is very easy, but it is possible to make silly mistakes.

In many/most cases it is unnecessarily explicit and verbose. However, as soon as you want to do things like:

  • skip first, or any other element
  • access several items in the array each (most commonly adjacent items: 01, 12, 23, 34, 45)
  • break / continue
  • modify the array – even the length of it – during the loop
  • sparse arrays, with undefined, it is obvious what you get

this becomes very natural with the good old loop. Doing it with the others will make it appear a bit contrived or the result may not be so obviously correct.

There is also something very explicit about the order. It may be true (or not?) that every implementation of JavaScript will always execute the other three loops in order. But you need to know that, to be absolutely sure, when reading the code. Not so with the good old for-loop. If order is a critical part of the algorithm and you may want to be explicit about it.

This is also the fastest loop.

The for-in-loop

for-in enumerates properties and loops over them. Do not use it for arrays:

  • it makes more sense to use for-in for Object, so the reader of the code may think your array is an object
  • are you 100% sure your array has no other enumerable properties, ever?
  • performance – this is by far the slowest loop
  • it is quite verbose

The for-of-loop

The for-of-loop is a bit “newer” and may not work in old browsers or JavaScript engines. That can be a reason to avoid it, but even more a reason why you do not see it in code you read.

I would argue this is the most practical, clean and simple loop, that should be used in most cases.

It is slightly slower than the good old for-loop, but faster than the other alternatives.

Array.forEach

I have been ranting about functional style code elsewhere. forEach is kind of an antipattern, because it is a functional construction that does nothing without a side-effect. A functional way to do something non-functional.

The callback function gets not ONE argument (as shown above), but actually 4 arguments. If you pass some standard function into forEach that can give you very strange results if the standard function happens to accept more than one argument and you did not know or think about it.

You get both index and array, so you can do horrible things like:

  array.forEach((current,i,array) => {
    const last = array[i-1];
    ..
  });

I have seen worse. Don’t do it. Functional programming is about being clear about your intentions. Use a good old for loop, or write your own higher-order-loop-function if you do the above thing often.

According to the documentation forEach loops in order. JavaScript is singlethreaded. But other languages may parallellize things like forEach, so I think the right way to think about forEach is that order should not matter. Best use for forEach are things like:

  ['gif','jpg','png'].forEach(registerImageFormat);
  players.forEach(updatePosition);

forEach is slower than the good old for-loop and for-of.

Sparse Arrays

I made an experment with a sparse (and worse) array:

  const array = ['first'];
  array[2] = 'last';
  array.x = 'off-side';
 
  let r = 'for';
  for ( let i=0 ; i<array.length ; i++ ) {
    r += ':' + array[i];
  }
  console.log(r);
 
  r = 'for-in';
  for ( const i in array ) {
    r += ':' + array[i];
  }
  console.log(r);

  r = 'for-of';
  for ( const x of array ) {
    r += ':' + x;
  }
  console.log(r);
 
  r = 'forEach';
  array.forEach((x) => {
    r += ':' + x;
  });
  console.log(r);

The output of this program is:

  for:first:undefined:last
  for-in:first:last:off-side
  for-of:first:undefined:last
  forEach:first:last

If this surprises you, think about how you code and what loops you use.

Performance

For a rather simple loop body here are some benchmarks

~160 M loopsMacBook Air 2014
node 14.16.0
RPI v2 900MHz
node 14.15.3
i7-8809G
node 12.18.3
i7-8809G
node 14.16.0
for ( i=0 ; i<array.length ; i++ )280ms3300ms200ms180ms
for ( i of array )440ms6500ms470ms340ms
for ( i in array )6100ms74000ms5900ms4100ms
array.forEach560ms10400ms480ms470ms

On one hand, a few milliseconds for a millions loops may not mean anything. On the other hand that could be a few milliseconds more latency or UI refresh delay.

Benromach: 7 wood finishes

I got the opportunity to try 7 different Benromach, all quite young, matured (finished) on different types of wood and casks. This is the result, from best to worst.

  1. PX Wood: 2002-2010
  2. Port Wood: 2000-2012
  3. Madeira Wood: -2008 (7YO+)
  4. Sassicaria Wood: 2002-2009
  5. Hermitage Wood: 2001-2010
  6. Pago Capellanes Picay Wood: 2002-2009
  7. Tokaji Wood: -2006 (5YO+)

In conclusion I can say I am quite unimpressed. All were quite thin in flavour and many had a significant taste of sulphur. There was little classic malty character overall. I also note that the commonly used casks/finishes ended up winning, and the more odd woods failing.

I actually blind tested these whiskies.

First round

In the first round I randomly picked 3 pairs of whisky (the last 7th bottle did not participate in the first round). This is the quarter finals.

Hermitage vs Port
Color: Same color.
Nose: Hermitage is more sweet and like desert wine. Port is less sweet and not peaty, but a hint in that direction. Mouth: Both tastes a bit of sulphur. Hermitage is thin, not very nice. The Port could pass as a light sherry matured whisky, it is richer.
Winner: Port.

Madeira vs Tokaji
Color: Madeira little darker.
Nose: Madeira is sweet classic sherry, a bit thin. Tokaji is thin, a bit fruity and a bit sour.
Mouth: Madeira is sweet, soft with a bit of caramel. Tokaji has much sulphur, quite dry wood and sour.
Winner: Madeira.

Sassicaria vs Pago Capellanes Picay
Color: Pago C a little darker.
Nose: Sassicaria smells wine in an elegant way, a little malty. Pago C has a woody sour smell.
Taste: Sassicaria is soft, balanced with a hint of sulphur. Pago C has much sulphur and is a bit rough wood.
Winner: Sassicaria.

Round 2

In the second round I let the 3 winners and the untested (PX Wood, by chance) whisky compete in semi finals. I randomly picked the two matches and blind tested.

PX vs Sassicaria
Color: Perhaps PX is slightly more pale.
Nose: PX has a wine/fruit aroma with a hint of sulphur. Sassicaria a bit sweeter and a bit malty.
Mouth: Both have some sulphur. I find PX a little fruity and salty, while Sassicaria is more dull.
Winner: PX

Madeira vs Port
Color: Port is darker
Nose: Both have an elegant wine and fruit aroma. Madeira a bit softer.
Mouth: Port is balanced with raisin and caramels, hint of sulphur. Madeira is lighter, more balanced and a little bit more rough.
Winner: Port.

I also randomly picked 2 of the 3 losers from round 1 and did a blind test between them.

Hermitage vs Pago Capellanes Picay
Color: Hermitage a bit paler.
Nose: Hermitage has en elegant wine aroma. Pago C is rougher with much sulphur.
Mouth: Hermitage has somewhat malty and balanced flavour, with some sulphur. With water it becomes quite decent but rather dull. Pago C has much sulphur and tastes immature. It is softer with more water, but still not good.
Winner: Hermitage.

Round 3

In round 3 we have the final, the game for 3rd place, and the game for (avoiding) last place.

Tokaji vs Pago Capellanes Picay (the two worst)
Color: Tokaji slightly paler
Nose: Tokaji sour and sulphur. Pago C more mellow.
Mouth: Tokaji mostly tastes sulphur and is disgusting. Pago C is somewhat softer, also mostly sulphur.
Winner: Pago C (I wasted most of both in the sink after deciding the winner)

Sassicaria vs Madeira (for the Bronze – I thought, see below)
Color: Similar
Nose: Sassicaria is like dry wine. Madeira is more fruity and sweet.
Mouth: Sassicaria has much sulphur, also some malty caramel. Madeira is more balanced with less sulphur.
Winner: Madeira

Port vs PX (for the Gold)
Color: Port is darker
Nose: Port smells raisins and little caramel. PX more balanced wine.
Mouth: Port is thin, with a hint of sulphur, but quite good. PX is caramel, little malt, and a hint of sulphur.
Winner: PX (with small margin)

Extra Round

I had to settle position 3 and 4. I blind tasted these two.

Madeira vs Hermitage
Color: Hermitage slightly darker
Nose: Some more fruitiness in Madeira, Hermitage more powerful, not necessarily a good thing.
Mouth: Madeira is with some reservatation a decently tasty whisky. Hermitage is a sulphur stinking rought mess.
Winner: Madeira (as already predicted in the original Bronze match).

Other Whisky

I will compare these 7 whiskies to other whisky. Check out my full head to head whisky list.

Benromach PX vs Glenmorangie Quinta Ruban
Color: Glenmorangie is darker.
Nose: Glenmorangie is fruitier, like peach or something sweet, and more rich and soft. Benromach more like a sherry whisky and with a hint of sulphur.
Mouth: Benromach is not exactly soft and rich, but somewhat balanced, with a hint of sulphur. Glenmorangie is more sweet, more soft, less sulphur. However, they are quite similar.
Winner: Glenmorangie Quinta Ruban.

Benromach Madeira vs Bushmills Banyuls
Color: Banyuls is darker.
Nose: Banyuls is sweeter, more bourbon. Benromach is more wine and sour.
Mouth: Bushmills richer, sweeter and more powerful. Benromach rather thin and dry in comparison. Bushmills, with more flavour, also has more of a lingering sulphur.
Winner: Bushmills Banyuls

Benromach Tokaji vs Grants
Color: Tokaji darker
Nose: Grants smells light malt and vanilla, Benromach something more undefined.
Mouth: Grants tastes light malt and vanilla. Benromach richer, more sweet/sour. Grants is softer, more chemical.
Winner: Grants (never appreciated Grants so much before, but it was quite close)

Benromach Hermitage vs Grants
Color: Hermitage is darker
Nose: Grants more vanilla and malt, Benromach more like sour desert wine.
Mouth: Grants kind of synthetic, Benromach somewhat balanced sweet and fruity.
Winner: Benromach (for more flavour and more interesting, Grants would have been the safe choice if I was offered a drink).

Benromach Tokaji vs J&B:
Color: J&B paler.
Nose: Benromach some undefined sherry fruity character, J&B mostly synthetic.
Mouth: Both tastes like cleaning products. J&B more soft and sweet. Benromach more acid.
Winner: Benromach (there is some interesting whisky flavour in it, but J&B is the safe choice).

Benromach Port vs Bushmills Banyuls
Color: Same (quite dark)
Nose: Benromach quite light fresh wine, after a while a bit more oily. Bushmills caramel and vanilla sweet, more powerful.
Mouth: Benromach quite sweet, a bit rough but also with some quality fruity flavour and sweetness, and a hint of sulphur lingering. Bushmills more sour, rougher, less flavour and more sulphur.
Winner: Benromach

Benromach Port vs Dalmore 10 Vintage:
Color: Very similar (dark)
Nose: Both quite thin, Benromach more raw cask sulphur and fruity, Dalmore more classic but something odd synthetical about it.
Mouth: Dalmore has a thin, sweet classic flavour. Benromach seems raw and unrefined.
Winner: Dalmore

Benromach PX vs Dalmore 10 Vintage
Color: Dalmore slightly darker
Nose: Benromach a bit more raw and fruity, Dalmore more classic yet synthetic
Mouth: Benromach rougher, Dalmore softer. The synthetic thing in Dalmore is probably some funny wood remains.
Winner: Dalmore

Tokaji vs Johnny Walker Red Label
Color: Very similar
Nose: Red Label very light, a bit ethanol. Tokaji more sour (and some sulphur I would say)
Mouth: Red Label soft, not very much flavour, a bit honey. Tokaji is sour, rough and with a significant sulphur lingering.
WInner: I prefer Red Label.

Port vs Paul John Brilliance
Color: Paul John is paler.
Nose: Paul John is quite light, a bit fruity, and not so little raw wood. Benromach Port is more oily and heavy.
Mouth: Paul John is a bit dry in the mouth, yet sweet, some bitterness. Benromach is heavier, more flavour, perhpaps softer but also more sulphur. I add water to both, Benromach gets softer but Paul John gets thinner with more wood.
Winner: Benromach Wins

PX vs Paul John Classic Select
Color: Benromach a little darker
Nose: There is more sherry character (with a hint of sulphur) to PX, and a more woody character to Paul John.
Mouth: Classic Select is more soft (classic even), PX rather rough immature sherry.
Winner: Paul John.

Sassicaria vs Johnny Walker Red Label
Color: JW a little paler, or at least less reddish.
Nose: JW is light, a bit chemical. Sassicaria a bit fruit and a hint of sulphur.
Mouth: JW is soft and tastes reasonably good. Sassicaria has much sulphur.
Winner: JW Red Label.

Conclusion

This are all thin, immature whiskies mostly with sweet flavour. They are not particularly soft, and unfortunately sulphur is the common theme here.