54 votes

GMSPolyline très grand pic de mémoire

Dans une application GPS qui permet à l'utilisateur d'afficher une liste de complexe emplacement des points que nous appelons des pistes sur les différents types de carte, chaque piste peut être composé de 2k à 10k de points de localisation. Les pistes sont copieusement coupé, taillé et le chemin d'accès simplifié quand ils se sont rendus sur la non-Google map types. C'est pour l'utilisation de la mémoire vers le bas et de la performance. Nous avons généralement que du vent jusqu'à la soumission de beaucoup moins d'un millier d' (total) transformé emplacement des points pour le pipeline OpenGL, même dans le pire des cas.

L'intégration de Google Maps SDK pour iOS, nous avons d'abord tenté de continuer de tirer profit de notre propre OpenGL piste système de rendu, mais a couru dans les questions contradictoires OpenGL contexte d'utilisation (rendu travaillé, mais nous ne pouvions pas obtenir GMSMapView et nos propres ressources OpenGL à la fois la mise en liberté sans que quelqu'un touchant supprimé de la mémoire).

Nous essayons donc de tirer parti de la GMSPolyline constructions et laissez les Google SDK faire la piste de rendu, mais nous avons exécuté dans majeur de l'utilisation de la mémoire de questions, et sont à la recherche pour le guider dans le travail autour d'eux.

En utilisant Xcode Instruments, nous avons surveillé l'utilisation de la mémoire lors de la création d'environ 25 poly lignes avec environ 23k emplacement total de points (et non pas de chaque). Au cours de poly ligne de création, d'application l'utilisation de la mémoire augmente d'environ 14 MO environ 172 MO, un net pic de l'ordre de 158 MO. Peu de temps après tous les poly lignes sont créées, l'utilisation de la mémoire, enfin, revient à environ 19 MO et semble stable, pour un cumulatif net de l'ordre de 5 MO, donc il semble que chaque point d'emplacement nécessite environ 220 octets (5 MO / 23k points) pour stocker.

Ce qui nous fait du mal est l'utilisation maximale de la mémoire. Alors que notre test de laboratoire utilisé uniquement 23k points de localisation, dans le monde réel, il y a souvent beaucoup plus, et iOS semble renoncer à notre application après Google Maps a consommé environ 450 MO sur un iPhone 5 (alors que notre internes poly ligne système de rendu des pics à près de 12 MO pour le même cas de test).

Clairement l' GMSPolyLine construire n'est pas prévu pour le poids lourd de l'utilisation que nous avons besoin.

Nous avons essayé d'emballage de certains de la poly création de la ligne de boucles séparées autorelease piscines, et puis la vidange ceux à certains moments, mais cela n'a aucune incidence sur l'utilisation de la mémoire. Le pic d'utilisation de mémoire après la poly lignes sont créées et le contrôle est retourné à la course principale de la boucle n'a pas changé du tout. Plus tard, il est devenu clair pourquoi; la Carte de Google, le système n'est pas en libérant les ressources jusqu'à la première DisplayLink de rappel après le poly lignes sont créées.

Notre prochain effort sera manuellement limiter la quantité de données que nous poussant à GMSPolyline, probablement à l'aide de nos propres limites de test, de coupure, de l'élagage et de la minimisation, plutôt que de compter sur Google Maps pour le faire efficacement.

L'inconvénient est que cela signifie beaucoup plus de GMSPolyline objets seront alloués et libéré, potentiellement, tandis que l'utilisateur est un panoramique, un zoom autour de la carte. Chacun de ces objets auront beaucoup moins de points de localisation, et pourtant, nous sommes préoccupés des conséquences imprévues de cette approche, caché surcharge de nombreux GMSPolyline allocations et désallouer.

La question est donc, quelle est la meilleure approche pour faire face à cette situation, et quelqu'un de Google de jeter un peu de lumière sur tout GMSPolyline les meilleures pratiques, les limites supérieures de l', goulots d'étranglement, etc. ?

1voto

user3271402 Points 26

pourquoi ne pas vous essayez d'utiliser l'API de google pour la direction, basée sur la base de requêtes http. https://developers.google.com/maps/documentation/directions/ . (consulter les conditions sur la concession de licences et le nombre de demandes).

Et puis de tracer les données avec IOS MKPolyline. im Sûr que vous aurez de meilleures performances. Et vous seulement dépendre de google pour les données de positionnement.

pour convertir la réponse de l'API de google afin de coordonnées, utilisez la méthode bien connue (prises à partir d'autres post) ci-dessous:

- (NSMutableArray *)parseResponse:(NSDictionary *)response
{
    NSArray *routes = [response objectForKey:@"routes"];
    NSDictionary *route = [routes lastObject];
    if (route) {
        NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"];
        return  [self decodePolyLine:overviewPolyline];
    }
    return nil;
}


-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {

    NSMutableString *encoded = [[NSMutableString alloc]initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch range:NSMakeRange(0,
                                                                          [encoded length])];
    NSInteger len = [encoded length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init]; NSInteger lat=0;
    NSInteger lng=0;
    while (index < len) {
        NSInteger b; NSInteger shift = 0; NSInteger result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlat = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lat += dlat;
        shift = 0; result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlng = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5]; NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
        CLLocation *location = [[CLLocation alloc] initWithLatitude: [latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location]; }
    return array;
}

J'ai eu un problème similaire avec des performances sur google sdk et il travailler pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X