2
\$\begingroup\$

I created an rxjs search for a hiring company, but I got rejected for the following reason: -performance issue on a bigger data set. -bugs

My question is how can I make this code better for the next time if I have similar task?

brands = These should be populated from the brand property from the collection of products.

The search should match using the name, description and brand properties.

  • The search should not fire unless a minimum of three characters have been typed.
  • The search should only fire a maximum of once per 400 milliseconds.

If searching for “xxx” with the brand selected as “xxx” and In Stock, then only products matching all three filters

const stackoverflowFilter = (filter: ISearch) => {
  return (product: IProducts): boolean => {
    return ((
      (
        (product.name.toLowerCase().indexOf(filter.input.toLowerCase()) !== -1) ||
        product.description.toLowerCase().indexOf(filter.input.toLowerCase()) !== -1 ||
        product.brand.toLowerCase().indexOf(filter.input.toLowerCase()) !== -1) &&
      product.brand.toLowerCase().indexOf(filter.select.toLowerCase()) !== -1 &&
      (filter.radio === 'all' ? true : filter.radio === 'in-stock' ? product.quantity > 0 : product.quantity === 0)
    )
    )
  };
};

export interface ISearch { input: string; select: string; radio: string }



> public getStackoverflow(): Observable<Stackoverflow[]> {
>         return of([
>           {
>             id: "1",
>             name: "This is just test data",
>             price: "89.9",
>             description: "test data",
>             brand: "stackoverflow",
>             quantity: 4
>           }....])}



 this.stackoverflow$ = this.service.getStackoverflow();

    this.stackoverflow$.pipe(
      tap((prod) => {
        this.stackoverflow = prod;
        this.brands = this.stackoverflow.map(({ brand }) => brand).reduce((prev, cur) => {
          if (prev.indexOf(cur) < 0) prev.push(cur);
          return prev;
        }, []);
      }),
      concatMap(() =>
        this.search$.pipe(
          debounceTime(400),
          distinctUntilChanged(),
          switchMap((search: string) =>
            iif(() => search.length >= 3,
              this.stackoverflow$.pipe(
                map(stackoverflow=> stackoverflow.filter(stackoverflowFilter(this.filter))),
                distinctUntilChanged((curr, prev) => curr === prev),
              ),
              this.stackoverflow$.pipe(
                filter(() => search.length === 0),
              )
            )
          )
        ))
    ).subscribe(
      stackoverflow=> { this.stackoverflow= stackoverflow; },
      (err) => throwError(err)
    );
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

If there are 1 million datasets, and i enter the first three letters, it will have to filter all 1 millionen values (let us asume the result will be 200 hits). When i now add a fourth letter, it will have to filter AGAIN all 1 million values and not just the 200 hits.

Therefor, if it is absolutly necessary to do the filtering codewise, then you could implement a kind of memory effect.

When the first filtering is executed (after the first 3 letters), you store the searchphrase and the filter result. When now the fourth letter is added, you just check if the first three letters are still the same. If yes, then you can shorten your filtering by just filtering the reduced list from the filtering before.

That way you swap runtime against memory consumption (a typical trade off).

My question would be if it is absolutly necessary to do the filtering codewise. When this search should be applied mostly on big datasets, then i would move the filtering to the backend. Then you have a lot more of requests to the backend, but the backend (the database to be precise) could handle such filtering much more efficiently.

But as always, it depends. For small sets of data, the roundtrip time (FE -> BE -> FE) for each search request will eat all performance gains that you have aquired with the more efficient filtering. But for large datasets, the roundtrip time will be less bad, in comparision to the filtering performance (and the memory consumption) on the client.

warm regards Jan

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.