Marko Zadravec
Marko Zadravec

Reputation: 8730

Optimize function with creating NSDictionarry

I am trying to optimize function which returns NSMutableDictionary like this :

 -(NSMutableDictionary *)getValuses{

    NSNumber *n1 = [NSNumber numberWithInt:-1];
    NSNumber *n2 = [NSNumber numberWithInt:-1];
    NSNumber *n3 = [NSNumber numberWithInt:-1];
    NSNumber *n4 = [NSNumber numberWithInt:-1];
    NSNumber *n5 = [NSNumber numberWithInt:-1];

    if (self.k1)
        n1 = self.k1;
    if (self.k2)
        n2 = self.k2;
    if (self.k3)
        n3 = self.k3;
    if (self.k4)
        n4 = self.k4;
    if (self.k5)
        n5 = self.k5;

    NSMutableDictionary * dictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:n1,[NSNumber numberWithInt:2],n2,[NSNumber numberWithInt:3],n3,[NSNumber numberWithInt:4],n4,[NSNumber numberWithInt:5],n5,[NSNumber numberWithInt:6], nil];

    return dictionary;
}  

I run this function in loop more than 1 000 000 times, so any optimisation is good. It works but I want it to work significantly faster.

Upvotes: 0

Views: 98

Answers (5)

Manuel M.
Manuel M.

Reputation: 4515

Try this! dispatch_appy method is for create loops and execute the code inside in concurrent queues. This is a better way of executing big loops.

dispatch_apply blocks - Apple Documentation

I didn't compile it but it should work. Hope it help to give you a clue. Good luck!

-(NSMutableDictionary *)getValuses{

    //add the values here
    NSMutableArray *array = [@[self.k1,self.k2,self.k3,self.k4,self.k5]mutableCopy];
    NSMutableDictionary * dictionary = [@{}mutableCopy];

    //this kind of block is better for big loops...
    size_t count = array.count;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_apply(count, queue, ^(size_t i) {
        id value = [array objectAtIndex:i];
        [dictionary setObject:value?value:(@-1) forKey:@(i)];
    });

    return dictionary;
}

Upvotes: 0

CRD
CRD

Reputation: 53000

You can reduce the number of NSNumber objects created, and you can use the new literal syntax to at least make the code shorter & easier to read. You can also halve the number of property accesses. Whether any of this will have a big impact on performance you'll have to find out.

-(NSMutableDictionary *)getValuses
{
   NSNumber *n = @(-1);

   return @{ @2: (self.k1 ?: n), @3: (self.k2 ?: n), @4: (self.k3 ?: n),
             @5: (self.k4 ?: n), @6: (self.k5 ?: n)
           };
}

(The expression a ?: b is shorthand for a ? a : b but a will only be evaluated once, hence the halving of the number of property accesses.)

Upvotes: 0

HaneTV
HaneTV

Reputation: 926

do you really need dictionnary with -1 values ? you can avoid all the "if/then" stuff (I heard it can be quite slow for a cpu) if you just do

    NSMutableDictionary * dictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:k1,[NSNumber numberWithInt:2],k2,[NSNumber numberWithInt:3],k3,[NSNumber numberWithInt:4],k4,[NSNumber numberWithInt:5],k5,[NSNumber numberWithInt:6], nil];
    // then you can do things like this
    id obj = [dictionary objectForKey:@2];
    if (obj)
        NSLog(@"dict with good values");
    else
        NSLog(@"old dict with -1");

Upvotes: 1

Andrey Gordeev
Andrey Gordeev

Reputation: 32459

You can try something like this (not tested):

-(NSMutableDictionary *)getValuses {
    NSNumber *n = [NSNumber numberWithInt:-1];
    NSMutableDictionary * dictionary = 
        [[NSMutableDictionary alloc] initWithObjectsAndKeys: 
            self.k1 ? self.k1 : n,[NSNumber numberWithInt:2],
            self.k2 ? self.k2 : n,[NSNumber numberWithInt:3]...
    return dictionary;
}

Upvotes: 0

Raon
Raon

Reputation: 1286

-(NSMutableDictionary *)getValuses{

    NSNumber *n1 = [NSNumber numberWithInt:-1];
   NSMutableDictionary * dictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:(self.k1)? self.k1:n1,[NSNumber numberWithInt:2],(self.k2)? self.k2:n1,[NSNumber numberWithInt:3],(self.k3)? self.k3:n1,[NSNumber numberWithInt:4],(self.k4)? self.k4:n1,[NSNumber numberWithInt:5],(self.k5)? self.k5:n1,[NSNumber numberWithInt:6], nil];

    return dictionary;
}

try the above code....

Upvotes: 1

Related Questions