简体   繁体   中英

Optimization of sorting and filtering array of objects

I have working code, and wish to get better performance from this as it gets pretty loaded if more data is passed. But I don't know what else can I do about it.

Input: array with logUnits, each containing a view of log event like "2013-01-16 15:13:00 Hello" and array of times - this array containts only times where we have log events (2013-01-02,2013-01-09 and etc)

Output: array of views where each view containts log units of the same day.

I also may need log units to be filtered by event type.

Here is how I did this.

 NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:times.count];
    @autoreleasepool {

        for(int x = 0; x != times.count; x++)
        {
            UIView *foo = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
            foo.backgroundColor = [UIColor clearColor];
            int f = 0;
            int h = 0;

            for(int i = 0; i != objectArray.count; i++)
            {
                @autoreleasepool
                {

                    LogUnit *unit = [objectArray objectAtIndex:i];
                    if([[times objectAtIndex:x] isEqual:[unit realTime]]) 
                    {

                        if(![[foo subviews] containsObject:unit.view]) // Look if unit was already added
                        {
                            NSString *number = [NSString stringWithFormat:@"SortLog%i ",[[NSUserDefaults standardUserDefaults] stringForKey:@"ObjectNumber"].intValue];
                            NSString *comp = [[NSUserDefaults standardUserDefaults] stringForKey:number];

                            if([[unit status] isEqualToString:comp] || [comp isEqualToString:NULL] || comp == NULL)
                            {
                                if([unit getEvent] != NULL)
                                {
                                    unit.view.frame = CGRectMake(unit.view.frame.origin.x, f * unit.view.frame.size.height + 30, unit.view.frame.size.width, unit.view.frame.size.height);
                                    [foo addSubview:unit.view];
                                    f++;
                                    h = unit.view.frame.size.height * f;
                                }
                            }
                        }
                    }
                }
            }

            foo.frame = CGRectMake(0,0, 320, h + 30 );
            h = 0;
            [views addObject:foo];
        }

I guess the worst thing in this is loop in a loop and for each outer loop i have to rerun all the logUnits. But don't know how else I could do this. Maybe there is a way to call something like "select unit where time equals [unit realtime]" Any ideas ?

There are a few red flags here. The lowest hanging fruit is that you are scanning though all of the subviews of foo for unit.view, which is an O(n) operation, which really hurt in the innermost loop.

Next, if you sort both arrays by time, you don't really have to do an double loop to find events that are the same size. See how it is done in merge sort.

If that is still not good enough, consider doing all of the comparison work on a side thread, and only dispatch the add subviews and view creation process back to the main thread. It.will at least make it seem a lot faster.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM