Copier un tableau de structures avec l’approche memcpy vs directe

Supposons que pp soit un pointeur sur un tableau de structures de longueur n. [a été alloué dynamicment] Supposons que je veuille créer une copie de ce tableau de structures et lui faire un pointeur, de la manière suivante:

struct someStruct* pp2 = malloc(_appropriate_size_); memcpy(pp2, pp, _appropriate_length_); 

Je peux aussi faire une boucle et faire pp2[i]=pp[i] pour 0 <= i <= n .

Quelle est la différence entre ces approches et laquelle est la meilleure et pourquoi?

Il n’y a pas de réponse définitive pour toutes les architectures. Vous devez faire un profilage pour déterminer quelle méthode est la meilleure.

Cependant, à mon memcpy j’imagine que la memcpy serait plus rapide simplement si quelqu’un a pris le temps de votre architecture / plate-forme particulière et est capable d’utiliser des nuances particulières pour accélérer les choses.

Le premier utilise des identifiants interdits dans C: tout ce qui porte le préfixe _ . Ce dernier n’est pas valide dans C89, car l’affectation de la structure a été rationalisée dans C99. En supposant qu’aucun de ces facteurs ne cause de problèmes, il n’y a pas de différence fonctionnelle.

Mieux n’est pas bien défini; Si vous définissez “mieux” comme compilé dans C89 , alors le premier pourrait être meilleur. Cependant, si vous définissez “mieux” sans comportement indéfini dans C99 , ce dernier est meilleur. Si vous définissez “mieux” comme étant plus optimal , il n’y a pas de réponse définitive, car une implémentation peut produire de mauvaises performances pour les deux, alors qu’une autre peut produire de mauvaises performances pour un code parfaitement optimal pour l’autre, voire le même code pour les deux. De toute façon, il est peu probable que cela crée un goulot d’étranglement dans votre algorithme …

Je dirais que la mémoire est plus rapide – généralement adaptée à la plate-forme sous-jacente et peut éventuellement utiliser des transferts initiés par DMA (sans copies de cache L1 / L2). La boucle for peut éventuellement impliquer des transferts supplémentaires. Cependant, cela dépend de l’intelligence du compilateur sous-jacent – s’il détecte une valeur définie statiquement pour n, il peut la remplacer par memcpy. Cela vaut la peine de chronométrer les routines ou de vérifier le code d’assemblage, comme le mentionnait Mystical.