Moyen efficace d'écrire beaucoup de lignes dans un fichier texte

J'ai commencé à faire quelque chose comme suit:

using (TextWriter textWriter = new StreamWriter(filePath, append))
{
    foreach (MyClassA myClassA in myClassAs)
    {
        textWriter.WriteLine(myIO.GetCharArray(myClassA));

        if (myClassA.MyClassBs != null)
            myClassA.MyClassBs.ToList()
                .ForEach(myClassB =>
                    textWriter.WriteLine(myIO.GetCharArray((myClassB)));

        if (myClassA.MyClassCs != null)
            myClassA.MyClassCs.ToList()
                .ForEach(myClassC =>
                    textWriter.WriteLine(myIO.GetCharArray(myClassC)));
    }
}

Cela semblait assez lent (~35 secondes pour 35 000 lignes).

Puis j'ai essayé de suivre l'exemple ici à créer une zone tampon, avec le code suivant, mais il n'a pas gain de moi quoi que ce soit. J'ai été voir encore temps d'environ 35 secondes. Est-il une erreur dans la façon dont j'ai mis en place le tampon?

using (TextWriter textWriter = new StreamWriter(filePath, append))
{
    char[] newLineChars = Environment.NewLine.ToCharArray();
    //Chunk through 10 lines at a time.
    int bufferSize = 500 * (RECORD_SIZE + newLineChars.Count());
    char[] buffer = new char[bufferSize];
    int recordLineSize = RECORD_SIZE + newLineChars.Count();
    int bufferIndex = 0;

    foreach (MyClassA myClassA in myClassAs)
    {
        IEnumerable<IMyClass> myClasses =
            new List<IMyClass> { myClassA }
                .Union(myClassA.MyClassBs)
                .Union(myClassA.MyClassCs);

        foreach (IMyClass myClass in myClasses)
        {
            Array.Copy(myIO.GetCharArray(myClass).Concat(newLineChars).ToArray(),
                0, buffer, bufferIndex, recordLineSize);

            bufferIndex += recordLineSize;

            if (bufferIndex >= bufferSize)
            {
                textWriter.Write(buffer);

                bufferIndex = 0;
            }
        }
    }

    if (bufferIndex > 0)
        textWriter.Write(buffer);
}

Est-il un meilleur moyen pour y parvenir?

  • Avez-vous essayé d'utiliser StringBuilder et de construire la chaîne alors il suffit d'écrire une fois pour le fichier.
  • aucune raison particulière d'utiliser des tampons?
  • Comment êtes-vous certain que c'est vraiment le IO qui est le problème ici? Qu'advient-il si vous venez d'écrire à un StreamWriter enroulé autour d'une MemoryStream, par exemple?
  • Justifier à gauche le code pour plus de lisibilité. Qu'est-ce que MyClassBs?
  • MyClassB (ainsi que MyClassA et MyClassC) sont typiques POCOs. MyClassA contient une liste de MyClassBs et une liste de MyClassCs. Ne fait que répondre à votre question?
  • il est basé sur l'hypothèse qu'il y a des coûts rattachés à l'écriture d'une ligne qui est atténué par la rédaction de plus d'une ligne à la fois. Vous ne savez pas si c'est une précis hypothèse, mais j'ai eu l'idée de l'article, je me suis lié.
  • Je n'ai pas essayé. Je peux donner un coup de feu, bien que.
  • Comment savez-vous 35 secondes est "assez lent"? Test de l'OI de la première à obtenir certaines limites? avant de bricoler avec le code c#...
  • Skeet - j'ai essayé d'utiliser un MemoryStream comme vous l'avez suggéré, et il a fallu environ la même quantité de temps, donc je pense que le problème doit être avec le GetCharArray() la méthode. Je vais regarder un peu plus. Merci.
  • Ne demandez pas ce que MyClassA est. Demandé à ce que MyClassBs est. Liste? OverservableCollection? Énumérable? Peut-être en mesure d'éliminer la ToList() de l'appel.
  • MyClassBs est un IEnumerable<MyClassB>.
  • La baisse de la construction de toutes les lignes dans la mémoire, c'est que vous avez toutes les lignes dans la mémoire. E. g. j'ai écrit une exportation de données qui écrit les quelques milliards de lignes. Ce serait une perte pour le cache de l'impressionnante chaîne de caractères en mémoire.
  • Je suis d'accord si vous êtes à la production d'un milliard de lignes qu'il serait inefficace, mais si vous faites un peu alors ce serait bien. Sans connaître les détails, il est difficile de donner la bonne solution.

InformationsquelleAutor lintmouse | 2013-06-26