8
lorentz
4y

Let me guess, using regexes in the mousemove event handler isn't a great idea.
How fast are simple regexes, anyway?
I have /^(\d+)(.*)$/, because I want to animate a css property that might have some unit.

Comments
  • 8
    Depends on the engine. They're fine if you're debouncing the operation. And you should always debounce the n-thousand times per second events.
  • 2
    @SortOfTested how does one de bounce? By preventDefault?
  • 5
    @SortOfTested I used this before, but for some reason didn't think about it now. Thanks for reminding me.
    BTW I went with requestAnimationFrame, since this is a CSS action.
  • 3
  • 3
    What is it that you're trying to achieve? I feel like there would be a less expensive way to do it even if RegEx feels the most straightforward.
  • 4
    @melezorus34
    Debouncing is a gate between invoking a costly operation and a producer which emits a large number of events in a small period of time.

    Basic js, it amounts to creating a setTimeout that you evaluates its existence on every iteration of the event on each fire of the event producer, which prevents execution of the expensive operation:

    let timeoutPtr;
    onScrollEvent = (time) => (evt => {
    if(this.timeoutPtr)
    clearTimeout(this.timeoutPtr);
    setTimeout(doExpensiveoperation, time);
    evt.preventDefault();
    });
    doExpensiveOperation(){ //much more expensive op here;
    this.timeoutPtr = null;
    }

    I prefer rxjs for tasks like this
    let debounceSubscription = (eventProducer: UIEvent, time: number, operation: () => void) => from(eventProducer)
    .pipe(debounceTime(time))
    .subscribe(operation);

    lodash, underscore, and I believe ramda also have features to support this.

    Note: There are some amateur-hour, brand building articles on medium with high search engine rankings that confuse debouncing with throttling, here's the difference:

    throttle: only allow n-operations per period
    debounce: only allow operations after n-period of no new event production
  • 2
    @Lor-inc
    Usually, I would absolutely agree on lmgtfy. This particular topic though, medium has poisoned the fuck out of, so I took a moment to set the record straight 🙂
  • 3
    @kamen Split a number from its unit while keeping both. I normally avoid regex in absence of a version that doesn't look like a mathematician's code that uses one letter symbols exclusively, but I figured this one would be simple enough and regex compilers tend to optimize.
  • 1
    @Lor-inc Should be trivial if the unit is fixed length:

    let str = '10px';
    let unit = str.substr(-2);
    let value = str.substr(0, str.length - 2);
  • 1
    @kamen It isn't. I don't know anything about the unit, it might not even exist. BTW I just realised that my regex only works with integers.
  • 1
    Test and see
  • 4
    @Lor-inc compare the last character. If it isnt a number, walk backwards until you find a number, then split the string. This should be faster than a regex.

    You can also optimize this with knowledge of units. For example, "%" is the only single-character unit. The only 3-length units are "rem" and "deg", and the only 4-char units are "vmin" and "vmax". With this you should be able to skip a compare or two -- and for something that runs 1k times a second, that's considerable.
  • 1
    @Lor-inc requestAnimationFrame is cool - I used that when I needed to do some stuff for the scroll event. It's pretty easy along with a status flag.
  • 2
    @Root
    This, great point.

    Definitely exploit the ascii bitwise check to implement this in a function. The substring variable processing will also need to happen inner-function, since js === being O(1) time relies on the string argument being interned in the closure behorehand, which only happens on assignment. If you try and substring compare another substring, it will be 0(n) time because of the function boundary.

    Interesting novelty in this case specifically in regards to v8's ignition and Tier-Up regexp compilation (instances of which are singleton), is modifying the pattern to /(.+)(rem|em|px|pt|%)/ may meet the special case in which the compiled DSA's O(n) byte span processing which would produce a 2-tuple of expressable,comparable with O(1) lookup on the comparable that may actually be faster than creating the new string out of the string unit.
  • 1
    @Root Good points, I'll definitely do that.
    @SortOfTested Actually the longest CSS units are exactly 4 bytes long so I might as well use the fact that they can be cast to an int and fit in a register... If it weren't for JS and how ints aren't a thing here.
Add Comment