Question

Je suis en train de faire une sérialisation personnalisée, et afin d'économiser un peu d'espace, je veux sérialiser les décimales comme int, si la valeur possible sage. La performance est une préoccupation, puisque je traite un volume élevé de données. L'utilisation actuelle de la méthode i est la suivante:

if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
    return true;
}

peut-il être amélioré?

Était-ce utile?

La solution

Avez-vous des valeurs négatives? Je suppose que oui puisque vous avez le contrôle MinValue, sinon vous pouvez l'ignorer. Vous pouvez même utiliser unsigned int qui vous permettra de convertir plus de vos valeurs doubles dans ints.

Modifier En outre, si vous avez des chiffres plus positifs, vous pouvez échanger les deux premières conditions. De cette façon, le premier est le plus susceptible d'échouer, ce qui diminue le nombre total de comparaisons.

Autres conseils

Vos critères d'invalidation sont:

1) Est-il supérieur à MaxValue?

2) Est-il plus petit que MinValue?

3) Est-ce qu'il contient un composant fractionnel?

Il semble que vous les avez couverts. Ma mise en œuvre serait:

public bool IsConvertibleToInt(decimal value)
{
    if(value > int.MaxValue)
       return false;

    if(value < int.MinValue)
       return false;

    if(Math.Floor(value) < value && Math.Ceiling(value) > value)
       return false;

    return true;
}

Comment à ce sujet. Je pense qu'il devrait prendre moins d'opérations (au moins un moins grand nombre de comparaisons):

    return (value == (Int32)value);

Souvenez-vous également, si une déclaration if retourne simplement une valeur booléenne, vous pouvez simplement retourner la comparaison. Cela seul pourrait le rendre plus rapide (à moins que le compilateur optimise déjà pour cela). Si vous avez, vous pouvez utiliser de la même l'instruction if faire ceci:

    if (value == (Int32)value)
    {
        //Do stuff...
    return true;
    }
    else
    {
        //Do stuff...
        return false;
    }

EDIT: Je sais que cela ne fonctionne pas vraiment. Je pensais le casting Int32 serait tout simplement copier dans les premiers 32 bits de la décimale, laissant derrière eux les bits restants (et ne pas jeter une exception), mais hélas, il ne fonctionne pas de cette façon (sans parler qu'il serait erroné toutes les valeurs négatives).

Il dépend du nombre de décimales que vous avez ou vraiment à. Si vous pouviez dire que je me soucie seulement jusqu'à 3 décimales alors le plus grand nombre, vous pouvez stocker dans int32 est Int.MaxValue / 1000. Si vous ne travaillez avec des chiffres positifs, alors vous pouvez obtenir un plus grand nombre en utilisant uint. En tout cas, la façon de le faire est d'espacer toujours réserve pour la décimale et l'utilisation * 1000 pour les coder et / 1000 pour les décoder à / de décimales.

Pas besoin de "valueAsInt =". Je crois (Decimal.ToInt32 (valeur) == valeur)) vous obtient le même résultat avec une affectation moins. Utilisez-vous valueAsInt comme une sorte de paramètre de sortie?

Souhaitez-vous pas être en mesure de faire quelque chose comme juste:

if(Decimal.ToInt32(value) == value)
{
     return true;
}

Pas un expert en .net, mais je pense que cela devrait être tout ce qu'il avait besoin. En outre, vos deux opérateurs de comparaisons devraient être « ou égale » depuis le min / max valeurs sont également valables.

Edit: Comme indiqué dans le commentaire, ce jetterait une exception. Vous pouvez essayer de capturer l'exception soit faux, mais à ce moment-là, il serait probablement beaucoup plus rapide pour faire le test min / max vous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top