La splendeur et la pauvreté de l'OLP - page 5

 
meat:

Ici, si je comprends bien, l'index est défini par une recherche binaire ?

Non, un accès direct comme dans un tableau.

__________

J'ai peut-être eu tort, je vais y réfléchir.

En général, rien ne vous empêche de créer un tableau pour toute la taille du type et d'obtenir un accès constant. (le commutateur ne fonctionne qu'avec les types intégraux).

Dans le cas que vous avez décrit, il est plus pratique de saisir une énumération.

 
TheXpert:

Non, un accès direct comme dans un tableau.

__________

J'ai peut-être réagi de manière excessive, je vais y repenser.

En général, rien ne vous empêche de créer un tableau pour toute la taille du type et d'obtenir un accès constant. (L'interrupteur ne fonctionne qu'avec les types intégraux).

Dans le cas que vous avez décrit, il serait plus pratique de créer une énumération.

Pour la valeur totale du type ? Pas question ! Dans ce cas, il faudra 16 Go de mémoire (pour un tableau de type int). Et quel est l'intérêt de prendre la valeur entière ? Le calcul de la différence entre les valeurs maximale et minimale suffira. Mais ce cas est de toute façon discutable, car pour les grandes valeurs, il faut d'abord négocier avec l'utilisateur la quantité de mémoire qu'il est prêt à allouer au programme. C'est pourquoi cette méthode ne convient que pour les petites valeurs de clé (ou plutôt pour une petite différence entre les valeurs maximale et minimale). Il ne reste donc que la recherche binaire.

 
meat:

Il ne reste donc que la recherche binaire.

Non, vous n'en avez pas vraiment besoin. En bref, si vous avez besoin de faire correspondre des nombres à un enum, vous avez besoin d'une recherche binaire, si travailler avec un enum et faire correspondre un enum à un nombre est suffisant, alors constant.

Je comprends pour la mémoire, c'est pourquoi j'ai écrit que j'en ai trop fait.

 

il est toujours possible de se poser la question "Pourquoi ?" en comparant le tableau d'affichage en ligne et dans le testeur. Le testeur n'a rien à voir avec la réalité...

tol64:

Avez-vous déjà donné une explication plus détaillée (preuve) quelque part ?

Vous devez étayer vos affirmations par des preuves, sinon vous ne les regardez même pas. ;)

 
C-4:
Les gars, lisez la documentation du commutateur. Un bon commutateur est une transition commutée dont les performances ne dépendent pas du nombre de choix. 1 choix, 100 ou 1000 - son taux de transition sera constant.
Wah merci, bonne référence, lu avec plaisir et bénéfice.
 
dimeon:

ilest toujours possible de se poser la question - Pourquoi? comparez le tableau d'affichage en ligne et dans le testeur. Le testeur n'a rien à voir avec la réalité...

Pour attirer l'attention. Ouvrez un nouveau fil de discussion et traitez votre question plus en détail. Montrez comment dans la réalité et comment dans le testeur. Proposez votre solution à ce problème. Sinon, elle restera "sans chance et sans option". )
 
Vinin:

Les preuves viendront de l'autre côté. Ou encore juste des mots.

En général, je ne suis intéressé que par les faits.

Bien que je sache déjà que la POO est plus lente, mais elle offre des commodités bien concrètes.

Comme promis, j'expose les résultats du profilage d'un projet. (Veuillez me pardonner, mais certaines fonctions sont masquées, car le code n'est pas destiné au grand public).

Pour commencer, je dirai qu'il s'agit d'un véritable projet de POO, avec une forte transformation des données sources. L'idée d'y utiliser la POO est poussée à l'extrême. Par exemple, il n'utilise pas du tout les variables globales, les tableaux, les fonctions en dehors des classes - parce qu'ils ne sont pas assez OOP. Pour que cela fonctionne, nous avons besoin de l'historique des ordres et des transactions effectués sur toute la période. L'analyse de 6014 transactions et de 6599 ordres ne prend que 3,1 secondes, soit 0,25 milliseconde par transaction, et la RAM nécessaire au déploiement de toutes les transactions, ordres et positions requiert environ 13 Mo, soit en moyenne 1 kilo-octet par transaction. - Je pense que c'est un très bon résultat pour une application OOP :

2014.07.07 12:44:33.464 TestMA (AUDCAD,H1) Nous commençons. L'analyse de l'historique des transactions (6014) et des commandes (6599) a duré 3,104 secondes. 13MB de RAM utilisés.

Mais regardons la structure du temps pris lors de l'initialisation de l'application :

Nous constatons que la plupart du temps est consacré à l'appel de la fonction AddNewDeal. Il s'agit d'une fonction composite et le travail réel est délégué à RecalcValues (57%). Il se compose à son tour de fonctions système telles que HistoryOrderGetInteger :

Notez que les temps d'appel de ces fonctions sont approximativement égaux.

Il convient de noter que c'est la fin de tout le convoyeur de fonctions. Avant d'arriver à ces calculs, vous devez passer une autre douzaine de méthodes OOP intermédiaires, et certaines d'entre elles sont également virtuelles. Mais leur temps de fonctionnement est négligeable et dans le profileur, ils se trouvent dans la deuxième moitié de la liste.

Comme il s'agit d'une application 100 % POO, il m'est très facile de suivre les sections de code où le temps est compté, et je peux très efficacement trouver de nouveaux moyens d'améliorer les performances. Je sais déjà que la partie restante (43 %) est constituée à 80-90 % d'appels à CArray.Resize(). À certains endroits, le code n'est pas optimisé et la répartition des tableaux se produit plus souvent que nécessaire. Je pourrais facilement réécrire ces modules OOP et améliorer les performances de 25 à 30 %. Sans la POO, ce serait plus difficile à faire car chaque fonction est potentiellement impliquée dans un nombre infini d'interrelations et il devient beaucoup plus difficile de calculer les conséquences des changements dans une telle fonction.

En conséquence, il s'avère que même un projet OOP complexe peut être amené à la limite de la performance des fonctions de base du système. Mais sans la POO, il sera plus difficile d'atteindre une telle productivité, car il y aura tellement de fonctions que tôt ou tard, vous ferez une erreur : vous ferez soit des appels inutiles, soit des jumeaux non optimisés, soit des implémentations trop complexes et lourdes.

 
dimeon:

il est toujours possible de se poser la question "Pourquoi ?" en comparant le tableau d'affichage en ligne et dans le testeur. Dans le testeur, cela n'a rien à voir avec la réalité...

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

La gloire et la misère de la POO

tol64, 2014.07.07 09:12

Pour attirer l'attention. Ouvrez un nouveau sujet et traitez votre question plus en détail. Montrez comment cela se passe dans la vie réelle et comment cela se passe dans le testeur. Suggérez votre propre solution à ce problème. Sinon, elle restera "sans chance et sans option". )

+++

àdimeon - Ouvrez un fil de discussion, vous apprendrez beaucoup d'arguments pour expliquer pourquoi il ne peut pas et pourquoi il devrait.

 
C-4:

Comme promis, j'affiche les résultats du profilage d'un projet. (Sans vouloir vous manquer de respect, certaines fonctions sont masquées car le code n'est pas destiné au grand public).

...

Pourquoi tout cela ? Vous n'avez pas cité les codes de vos fonctions (si ce n'est pour compter quelques fragments déchirés). Alors de quoi discuter ? Ici, le fil de discussion porte spécifiquement sur la comparaison des performances de la programmation OOP et procédurale. Et le fait que vos fonctions secrètes supposent d'effectuer un certain travail, de déléguer quelque chose quelque part, de prendre du temps, et que vous gérez tout cela de main de maître - bien sûr, nous sommes incroyablement heureux pour vous, mais à quoi servent ces informations, si nous ne voyons pas les codes.

 
meat:

Quel est le but de tout cela ? Vous n'avez pas cité les codes de vos fonctions (à moins que vous ne comptiez un fragment déchiré). Alors de quoi discuter ? Le sujet ici est spécifiquement de comparer les performances de la programmation OOP et procédurale. Et le fait que vos fonctions secrètes soient censées accomplir un certain travail, déléguer quelque chose quelque part, prendre du temps, et que vous gériez tout cela de main de maître - bien sûr, nous sommes incroyablement heureux pour vous, mais à quoi servent ces informations, si nous n'en voyons pas les codes.

Il a montré que l'appel direct ou l'appel virtuel n'ont aucun effet dans les projets réels.

Par l'exemple du profilage d'un vrai projet OOP, je montrerai que sa performance à la limite tend vers la performance des appels de fonction du système.

La grande majorité des coûts sont encourus dans l'appel des fonctions du système, où les programmes MQL passent le plus de temps. Les coûts d'organisation des appels sont négligeables par rapport à la charge utile.