Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving speed of List.search #679

Closed
sheffieldnikki opened this issue Mar 31, 2020 · 4 comments
Closed

Improving speed of List.search #679

sheffieldnikki opened this issue Mar 31, 2020 · 4 comments

Comments

@sheffieldnikki
Copy link
Contributor

sheffieldnikki commented Mar 31, 2020

For large numbers of items and/or slower CPUs the speed of searching can become noticeable. This drop-in replacement optimises the standard search function in list.js/src/search.js:

var search = {
    list: function() { ... }

with:

var search = {
    list: function() {
      for (var k = 0, kl = list.items.length; k < kl; k++) {
        var item = list.items[k];
        item.found = false;
        if (searchString === "") continue;
        var values = item.values();
        for (var j = 0, jl = columns.length; j < jl; j++) {
          var column = columns[j];
          if (values.hasOwnProperty(column) && values[column] !== undefined && values[column] !== null) {
            var text = (typeof values[column] !== 'string') ? values[column].toString() : values[column];
            if (text.toLowerCase().indexOf(searchString) !== -1) {
              item.found = true;
              break;
            }
          }
        }
      }
    }

Search is 63% faster in Chrome v80 and 30% faster in Firefox v74. The 2 biggest wins are replacing text.search(searchString) (for regular expressions, but List.js only supports searching on a string) with text.indexOf(searchString), and only calling .toString() in the inner loop if needed.

Here is a JSPerf comparing 3 different case-insensitive string matching functions.

@sheffieldnikki
Copy link
Contributor Author

sheffieldnikki commented Apr 1, 2020

You can also use this faster search without needing to modify the List.js library: just pass it as a custom search argument: see #678

listObj.search('Jonny', searchFunction); // Custom search for Jonny
listObj.search('Jonny', ['name'], searchFunction); // Custom search in the 'name' column

function searchFunction(searchString, columns) {
  for (var k = 0, kl = listObj.items.length; k < kl; k++) {
    var item = listObj.items[k];
    item.found = false;
    if (searchString === "") continue;
    var values = item.values();
    for (var j = 0, jl = columns.length; j < jl; j++) {
      var column = columns[j];
      if (values.hasOwnProperty(column) && values[column] !== undefined && values[column] !== null) {
        var text = (typeof values[column] !== 'string') ? values[column].toString() : values[column];
        if (text.toLowerCase().indexOf(searchString) !== -1) {
          item.found = true;
          break;
        }
      }
   }
};

@sheffieldnikki
Copy link
Contributor Author

Now updated to move item.values() call out of inner loop, thanks to @buczek

@javve
Copy link
Owner

javve commented Nov 25, 2020

This is awesome and now a part of #696 ❤️

@javve javve closed this as completed Nov 25, 2020
@javve
Copy link
Owner

javve commented Nov 25, 2020

It'll be release as part of v2.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants