0

I am testing with a set of about 5000 objects. I use a custom comparator(MyOwnSort) to sort values based on business logic.

    public Filter getFilter() {
    if (_filter == null) {
        _filter = new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String charText = constraint.toString();
                FilterResults filterResults = new FilterResults();

                // Clear the data
                visibleData.clear();
                for (String title : data) {
                    if (title.startsWith(charText)) {
                        visibleData.add(title);
                    }

                }

                myOwnSort.setSearchString(charText);
                Collections.sort(visibleData, myOwnSort);
            }

            filterResults.count=visibleData.size();
            filterResults.values=visibleData;

            return filterResults;
        }

        @Override
        protected void publishResults (CharSequence constraint, FilterResults results){

            notifyDataSetChanged();
        }
    } ;
}

return _filter;

}

This takes somewhere between 200 to 1600ms depending on the android device. This takes especially long when I start typing to filter the data as the data filtered is large. As you keep typing more, the dataset narrows down and it is faster. As you see, performFiltering is ran in background thread, so it does not block the ui thread. However the results don't show up immediately so it does not look snappy. Is this normal? Is there anything I can do to improve this? If not how can I make the experience better? Edit: Added the CustomComparator class.

class CustomComparator implements Comparator<String> {
    private String _searchString;

    public CustomSearchStringComparator(String searchString) {
        _searchString = searchString;
    }

    public void setSearchString(String searchString) {
        _searchString = searchString;
    }

    @Override
    public int compare(String lhs, String rhs) {
int res = customCompare(lhs, rhs);

        // finally alphabetic
        if (res == 0) {
            res = alphaCompare(lhs, rhs);
        }

        return res;
    }

    private int customCompare(String lhs, String rhs) {
            String lhsTitle = lhs.toLowerCase(Locale.getDefault());
            String rhsTitle = rhs.toLowerCase(Locale.getDefault());

            String[] lhsNames = lhsTitle.split("\\s+");
            String lhsFirstName = lhsNames[0];
            String lhsLastName = lhsNames.length > 1 ? lhsNames[1] : "";

            // if there is a middle name...
            if (lhsNames.length > 2) {
                lhsLastName = lhsNames[2];
            }

            String[] rhsNames = rhsTitle.split("\\s+");
            String rhsFirstName = rhsNames[0];
            String rhsLastName = rhsNames.length > 1 ? rhsNames[1] : "";

            // if there is a middle name...
            if (rhsNames.length > 2) {
                rhsLastName = rhsNames[2];
            }

            boolean lhsFirstNameContains = lhsFirstName.startsWith(_searchString);
            boolean rhsFirstNameContains = rhsFirstName.startsWith(_searchString);
            boolean lhsLastNameContains = lhsLastName.startsWith(_searchString);
            boolean rhsLastNameContains = rhsLastName.startsWith(_searchString);

            if (lhsFirstNameContains == rhsFirstNameContains) {
                if (lhsLastNameContains == rhsLastNameContains) {
                    return 0;
                } else {
                    return rhsLastNameContains ? 1 : -1;
                }
            } else {
                return rhsFirstNameContains ? 1 : -1;
            }
    }

   private int alphaCompare(String lhs, String rhs) {
        return String.CASE_INSENSITIVE_ORDER.compare(lhs, rhs);
    }
mobjug
  • 544
  • 1
  • 5
  • 13

1 Answers1

0

split("\s+") was the culprit as it was creating a pattern every time for regex evaluation. Since all that was needed is a simple split based on whitespace, I used Apache commons split method. This does a basic split and much faster and dramatically reduced the time by half.

mobjug
  • 544
  • 1
  • 5
  • 13