IFieldMergingCallback_FieldMerging speed question

Hi,

I have been researching performance of some larger documents when there are a large number of merge fields on the document. Today the code in FieldMerging looks like this:

    Private Sub IFieldMergingCallback_FieldMerging(ByVal e As Aspose.Words.MailMerging.FieldMergingArgs) Implements Aspose.Words.MailMerging.IFieldMergingCallback.FieldMerging
        If e.FieldValue IsNot Nothing AndAlso e.FieldValue.ToString.Trim() <> String.Empty Then
            Dim builder As DocumentBuilder = New DocumentBuilder(e.Document)
            Do While builder.MoveToMergeField(e.DocumentFieldName)
                If e.FieldName.StartsWith("HTML_") Then
                    builder.InsertHtml(e.FieldValue.ToString())
                Else
                    builder.Write(e.FieldValue.ToString())
                    e.Text = ""
                End If
            Loop
        End If
    End Sub

If I change that to:

    Private Sub IFieldMergingCallback_FieldMerging(ByVal e As Aspose.Words.MailMerging.FieldMergingArgs) Implements Aspose.Words.MailMerging.IFieldMergingCallback.FieldMerging
        If e.FieldValue IsNot Nothing AndAlso e.FieldValue.ToString.Trim() <> String.Empty Then
            Dim builder As DocumentBuilder = New DocumentBuilder(e.Document)
            Dim isHTMLField As Boolean = False
            If e.FieldName.StartsWith("HTML_") Then
                isHTMLField = True
            End If

            builder.MoveToField(e.Field, True)
            e.Field.Remove()

            If isHTMLField Then
                builder.InsertHtml(e.FieldValue.ToString())
            Else
                    builder.Write(e.FieldValue.ToString())
                    e.Text = ""
                End If
        End If
    End Sub

The change to MoveToField and even the addition of field.remove is substantially faster and seems to provide the same document outputs. Can you explain the performance difference or if there are any drawbacks to this change?

Thanks,
Ronnie

@rmoorehead

The performance difference you are observing between the two implementations of the IFieldMergingCallback_FieldMerging method is primarily due to how the DocumentBuilder interacts with the document’s structure.

In your original implementation, you are using a loop with MoveToMergeField to find each merge field by name repeatedly. This can be inefficient, especially in larger documents with many merge fields, as it requires the DocumentBuilder to traverse the document multiple times for each field.

In your revised implementation, you are using MoveToField to directly move to the specified field once, and then you remove the field immediately after processing it. This approach is more efficient because:

  1. Single Traversal: You only traverse the document once per field instead of potentially multiple times.
  2. Field Removal: By removing the field after processing, you prevent any future attempts to access it, which can further reduce overhead in subsequent merges.

The change to use MoveToField and the removal of the field can lead to significant performance improvements, especially in documents with a large number of merge fields.

As for drawbacks, the main consideration is ensuring that the removal of the field does not affect any other logic in your application that might rely on the presence of that field later in the process. If your application logic is designed to handle fields being removed after processing, then this change should be safe.

Overall, your revised method is a more efficient approach for handling field merging in Aspose.Words, and it should yield better performance in scenarios with many merge fields.

@rmoorehead Actually, the second method implementation is more correct even if do not consider performance improvements. In the first implementation DocumentBuilder.MoveToMergeField method is used. This method moves document builder cursor to the merge field with the specified name. But if there are several occurrences of the same merge field in the document, the method moves to the first one. On other hand, in the second method DocumentBuilder.MoveToField method is used, which moves cursor to the exact field, which is been merged. So I see only pros in the second approach if compare to the first one.