1

I have a search function in my react-native app where I am searching keywords in an array of 15,000 elements. When I am performing the search on an Android device, the performance is good and fast enough. However, when I am performing the same action on an iOS device, the performance is way too slower than android. I have tried the release version of the app on real devices but the result was the same. If the search function is taking 1 sec on an android device, it's taking 4-5 sec on iOS devices. I tried it on Samsung galaxy S7 and iPhone 6s. I know the processor of the device does matter but the difference is significant. Here is my code:

let query = this.state.searchQuery;

    query = query.toString().toLowerCase();

    let lastChar = query.substr(query.length - 1);

    if (query.length !== 0 && lastChar !== ' ') {

        let self = this.state.allProductData;

        let keywords = query.split(" ");

        this.setState({
            keywordsSearching: keywords
        });

        if (keywords.length !== 0) {

            let arr = [];

            for (var index = 0, selfLen = self.length; index < selfLen; index++) {

                if (!this.state.isSearching) {
                    break;
                }

                let counter = 0;
                var obj = self[index];
                let product_name = (obj.product_name).toString().trim().replace(/ /g, '').toUpperCase();
                let product_code = (obj.product_code).toString().trim().replace(/ /g, '').toUpperCase();
                let product_desc = (obj.product_desc).toString().trim().replace(/ /g, '').toUpperCase();

                for (var i = 0, len = keywords.length; i < len; i++) {
                    var key = keywords[i];
                    key = key.toString().toUpperCase();
                    if ((product_name.search(key)) !== -1 || (product_code.search(key)) !== -1 || (product_desc.search(key)) !== -1) {
                        counter++;
                    } else {
                        counter--;
                    }
                }
                if (counter > 0 && counter >= keywords.length) {
                    if (obj.product_id !== undefined) {
                        arr.push(obj);
                    }
                }
            };

            this.setState({
                isSearching: false,
                searchResult: arr,
            });
        }

    }

Any suggestion on how I can improve the search performance?

Julfikar
  • 1,353
  • 2
  • 18
  • 35

1 Answers1

1

You could create a swift module for this operation to run faster.

Here you can find the official tutorial on the react native website.

I did this before when I needed more performance on a local database and it is a great way to learn how react native works on ios at least.

krjw
  • 4,070
  • 1
  • 24
  • 49
  • Thanks for your suggestion. I will give a try. Any other suggestion besides creating native module? – Julfikar Oct 02 '18 at 09:12
  • Is this.state.allProductData an array or an object? searching through an array is mostly faster according to [this](https://stackoverflow.com/questions/17295056/array-vs-object-efficiency-in-javascript) – krjw Oct 02 '18 at 11:16
  • 1
    Also if this is an array you should look into using `map`, `filter` and `reduce`. Therre are good tutorials for these functions all over the internet. [Here](https://atendesigngroup.com/blog/array-map-filter-and-reduce-js) is one which I liked :) – krjw Oct 02 '18 at 11:24
  • this.state.allProductData is an array of objects. I have tried the `filter` and `every` functions of pure js and `lodash` but still same. Btw i was trying to create native module, but not sure why i'm getting an error `TypeError: Attempting to change the setter of an unconfigurable property` .. If I dont pass an array to the function, it's working fine. any suggetion? – Julfikar Oct 02 '18 at 16:41
  • could you paste the code somewhere? my react native time is a bit ago :) – krjw Oct 02 '18 at 18:43
  • I have pasted the code here : https://pastebin.com/C5AsGD8D Your help is appreciated ;) – Julfikar Oct 02 '18 at 23:59
  • I just made it work. But the problem is, it's blocking the UI and very slow. I am assigning threads for the function but still same – Julfikar Oct 03 '18 at 02:59
  • I looked at the code and couldn't find an obvious error. Which swift version are you using? 3? I think the `DISPATCH_QUEUE_PRIORITY_DEFAULT`constant is deprecated... use something like `.userInitiated` [here](https://stackoverflow.com/questions/37801370/how-do-i-dispatch-sync-dispatch-async-dispatch-after-etc-in-swift-3-swift-4) Maybe something else is blocking the UI? – krjw Oct 08 '18 at 06:45
  • It's objective C. `DISPATCH_QUEUE_PRIORITY_DEFAULT` is not deprecated in Objective C, I'm not sure about swift – Julfikar Oct 10 '18 at 04:18
  • Ok my bad! Unfortunately my objective c knowledge is really bad, I only have some experience in swift – krjw Oct 10 '18 at 06:53
  • Maybe it is possible to split the array and search for the result with different threads? Where do you get the data from? A database? Maybe it would be easier to always query the database? – krjw Oct 10 '18 at 06:55