blog.NOVALISTIC

Talk.CSS #56 with Eric Meyer and Daniel Tan

Remember in my last blog post I said Talk.CSS #56 would be a big one for me? Here’s why:

I presented my first ever CSS talk.

And I wasn’t alone in giving a talk today. I would have my turn… right after Eric Meyer.

Timestamps, courtesy of Makyen:

  1. 19:25 for Eric’s talk, Design in the background. Or watch separately via Engineers.SG.
  2. 58:48 for my talk, Introducing :is() and :where(). Or watch separately via Engineers.SG.

Before I get to the part about me, some brief thoughts on Hui Jing’s and Eric’s sharings:

So, getting to my talk now. Why the sudden decision to put together a presentation on PowerPoint about Selectors, my favorite thing? Because of this:

While it was super cool that we actually managed to get Eric to share with us, it was the last part of the tweet that had me shook: “this wind-up edition”. That’s right: Talk.CSS #56 was going to be the last ever Talk.CSS (meetup in this format, anyway).

You see, after I started speaking for the first time at Talk.CSS #46 at the beginning of the year, I had written this footnote:

:where(:is(#daniel.now))

Hey there. How are you doing? I hope you are well.

The COVID-19 outbreak has thrown everyone for a loop in both direct and indirect ways, and (I’m sure you and) I have been no exception. I’m happy to report that I have not caught the virus (Singapore has handled it well, for certain definitions of “well” I won’t get into), and will take utmost care to keep it that way.

My plan, as outlined in my birthday post for the year, was described thusly:

In the short term (i.e. sometime this month) I plan to update my battlestation with my biggest incremental update to Radiance yet. Beyond that I will continue to work on the updates to the LEGO Room that I mentioned last year, as well as miscellaneous housekeeping elsewhere on my site.

But in general, I will be taking things slow. I wish I didn’t have to, but right now I have to if I want to keep it together for a little longer, and to be clear it’s still a nice thing to be able to do, not something I’m reluctantly settling for. Talk to you later.

That biggest incremental update to Radiance yet actually happened. Praise God! However due to world-changing events that took place soon after, I never got to work on the LEGO Room. I’m still actively pursuing my LEGO hobby, but I just haven’t had the energy to also update the site along with it. Furthermore, in March a new version of the Brickset API was released, with the current version on which my site depends no longer functional as of this writing. This has not broken the LEGO Room in any way, but it has prevented me from updating my collection until I finish upgrading it to the new API. That is indeed in progress but, for obvious reasons, will take a while.

Having said that, I have indeed been taking things slow; in fact, slower this year than any other year. I’ve been focusing my time on recuperating mentally at home, and navigating the “perilous” new normal outside world as it slowly reopens. I’ve been playing plenty of video games (the then-newly released DOOM Eternal actually saved me from a crisis, believe it or not, and remains one of my favorite games of the year). I wrote only a single technical article (not counting Talk.CSS #46) and it was about JavaScript, and have left my site pretty much dormant and been nearly completely inactive on Stack Overflow. I even stepped down as a Microsoft MVP and am now in the MVP Reconnect program.

And I suspect I will continue to take things slow for the foreseeable future. But I’ll be at Talk.CSS #56 tomorrow after months of not attending, and it’ll be a big one for me. Maybe I’ll see you there.

Performance of Array.prototype.every(), Array.prototype.some()

I was writing a userscript a couple of weeks ago and had the opportunity to use Array.prototype.every()/some() for the first time. (I only needed one of them — I ended up going with some() for semantics reasons.)

This wasn’t a performance-critical context, but nevertheless I started to wonder if every() would immediately return false as soon as it found an element that didn’t meet the condition, and some() would immediately return true as soon as it found an element that did meet the condition.

MDN states that they do, but I wanted to see some numbers. So I ran a handful of quick n’ dirty tests in the Firefox console to check it out. For the sake of organization, here’s the setup:

function bench(label, test, loops) {
    loops = +loops || 10;
    let t = [];

    for (let i = 0; i < loops; ++i) {
        let tt = performance.now();
        test();
        t.push(performance.now() - tt);
    }

    let avg = Math.round(t.reduce((a, b) => a + b) / loops);
    console.log(`${label}: ${avg}ms avg of ${loops}`);
    return t.map(Math.round);
}

const a = [1, 1, 1, 1, 1, 1, 1, 1], b = [0, 0, 0, 0, 0, 0, 0, 0];
const isEqualToOne = n => n === 1;

Here are the tests:

bench('every() is true', () => {
    for (let i = 0; i < 10_000_000; ++i)
        a.every(isEqualToOne);
});

bench('every() is false', () => {
    for (let i = 0; i < 10_000_000; ++i)
        b.every(isEqualToOne);
});

bench('some() is true', () => {
    for (let i = 0; i < 10_000_000; ++i)
        a.some(isEqualToOne);
});

bench('some() is false', () => {
    for (let i = 0; i < 10_000_000; ++i)
        b.some(isEqualToOne);
});

Here are the relevant computer specs:

And here are the results in Firefox 74.0:

every() is true: 1501ms avg of 10
every() is false: 1382ms avg of 10
some() is true: 1339ms avg of 10
some() is false: 1459ms avg of 10

It looks like there is indeed a difference, albeit a small one. Specifically,

I wanted to see how the results compared in other browsers, so I attempted to run these tests in both the new and legacy versions of Microsoft Edge, as well as Chrome. In doing so, I discovered that V8 and Chakra appear to cache function calls after the first couple of iterations, causing subsequent iterations to clock far shorter times and invalidating the output of bench().

Frustratingly, there does not appear to be a way to disable this behavior, so I had to significantly decrease the iteration count using the loops parameter I just happened to have had the foresight to include. I also had to decrease the number of calls to every() and some() in Edge Legacy and increase it in the new Edge and in Chrome to get reasonable times.

Here are the results:

(Yes, I really did have to limit it to just 2 iterations in V8 before it started caching.)

The difference appears significantly larger in Chakra at 22.6%/27.2% faster, and is just ridiculous in V8 at a whopping 67%/64% faster. It’s not immediately clear to me why when I compare the source implementations, so perhaps someone more familiar with the code might be able to shed some light? It doesn’t help that the SpiderMonkey and ChakraCore implementations are literally just JavaScript, so it’s got to be something way under the hood. But here are the links anyway:

All told, since I was just writing a userscript for Firefox, which is my daily driver, for personal use, I’m not too worried. But I did learn a thing or two about Array.prototype.every() and Array.prototype.some(), more than I bargained for, and I thought it might interest other JS performance junkies, which is why I’ve blogged about it. Hope you learned from it, too.

Talk.CSS #46

Well, I haven’t blogged about Talk.CSS since my first two times there. That’s not good. I had a few more but I never got around to them due to chronic illness, executive dysfunction and whatnot. But today, the only thing I’m down with (and have been since Tuesday) is a throat infection that hasn’t gotten worse yet, so I’m making the most of tonight by pushing this one out.

So I went to Talk.CSS today, the first of the year. This time it’s at Microsoft Singapore’s new office at Frasers Tower. It would be my first time there after my last visit to the old office for last year’s Insider Dev Tour, so I was pumped.

But this being a new environment, I had to take precautions to ensure things went as smoothly as possible. To that end I pinged Hui Jing and Gao Wei on Twitter:

And then I had the brilliant idea of going through Sarah, my Microsoft MVP contact from Microsoft Singapore, as well. It would be my first time meeting her in person. She said she’d pick me up after finishing her meeting; I couldn’t go inside so I waited at the lobby for her.

Turns out, when I first got to the lobby, I was so calm that I could confidently decide to tweet this to the former two:

That’s right: even before I’d set foot in the new office, my selective mutism was already a no-show. This could have partly been because I made it a point to be early so I had time to collect myself, but I’m serious, it’s all Microsoft. My 11 years of guaranteed speech at the old office appear to have carried over seamlessly.

Anyway, Sarah came to pick me up first; it would be another 10 minutes before Hui Jing got there. Naturally, she was the first person I spoke to.

And here I was, at Microsoft Singapore’s new office at Frasers Tower:

The Microsoft logo at the new Singapore office.
The Microsoft logo at the new Singapore office.

Read on for Hui Jing’s reaction to hearing my voice for the first time and, of course, the talks themselves! I know the talks are probably what you came here for but this experience was particularly important to me so I just had to share. Let a disabled person have their limelight, won’t you?

It’s my 28th birthday!

Happy birthday to me, I’m officially 28! This afternoon I got to see Spies in Disguise with some folks from church I’m comfortable with, breaking a 16-year curse of never having a proper even-numbered birthday celebration with anyone. And while I was really scared sitting in the pitch-black cinema for several minutes, when the screen finally came on it did so with no sudden sound effects and I was never startled. I’m pretty glad.

Spies in Disguise poster.
Spies in Disguise poster.

Anyway, elephant in the room — I never got around to making my announcement regarding Stack Overflow, and I’m still not ready to say a word about my life situation in general. I will say that my current break from the site

  1. is intermittent,
  2. is unplanned, and
  3. has very little to do with anything on part of Stack management.

Oh and I still have no plans to step down as moderator, so don’t worry. Things aren’t terrible on my end. In the short term (i.e. sometime this month) I plan to update my battlestation with my biggest incremental update to Radiance yet. Beyond that I will continue to work on the updates to the LEGO Room that I mentioned last year, as well as miscellaneous housekeeping elsewhere on my site.

But in general, I will be taking things slow. I wish I didn’t have to, but right now I have to if I want to keep it together for a little longer, and to be clear it’s still a nice thing to be able to do, not something I’m reluctantly settling for. Talk to you later.