Hi, below is a byte array to string encoder. It uses the yEnc algorithm that is used for Usenet binaries (Usenet only supports text).

Doing a performance analysis in VS2010 shows that this is the most CPU intensive part of the application.

The encoder function is used thousands of times, so I'd like to optimize it as much as possible.
Does anybody know if more improvements can be made?

I'm using 'ReDim Preserve' instead of 'Take()ToArray', because I'm targeting .NET Framework 2.0. Is there a more efficient way of getting only a part of a byte array?


vb.net Code:
  1. 'Values for yEnc Encoder
  2. Public Structure EncoderValues
  3.     Public lChar As Byte
  4.     Public IsSingleChar As Boolean
  5.     Public CheckLine0 As Boolean
  6.     Public Line0Char As Byte
  7. End Structure
  8. Public m_EncoderTable(255) As EncoderValues
  9.  
  10. 'This is called in the Form_Load event.
  11. Public Sub SetupEncoder()
  12.     Dim lngInput As Integer, bTest As Byte
  13.     For lngInput = 0 To 255
  14.         With m_EncoderTable(lngInput)
  15.             bTest = CByte((lngInput + 42) Mod 256)
  16.             Select Case bTest
  17.                 Case 1 To 8, 11 To 12, 14 To 45, 47 To 60, 62 To 255    'Normal processing
  18.                     .lChar = bTest
  19.                     .IsSingleChar = True
  20.                 Case 46                                           'Test for column one, escape if in that col.
  21.                     .lChar = bTest
  22.                     .IsSingleChar = False
  23.                     .CheckLine0 = True
  24.                     .Line0Char = CByte((bTest + 64) Mod 256)
  25.                 Case Else                                         'Critical char, needs to be escaped.
  26.                     .lChar = CByte((bTest + 64) Mod 256)
  27.                     .IsSingleChar = False
  28.             End Select
  29.         End With
  30.     Next lngInput
  31. End Sub
  32.  
  33.  
  34. Public Function EncodeData(ByVal bIn() As Byte) As String
  35.  
  36.     Dim bOut() As Byte, lChar As Integer, lPos As Integer, lLine As Integer
  37.  
  38.     ReDim bOut(UBound(bIn) * 2)             'Make the output buffer.  Double size will almost always be enough.  2 extra
  39.     'chars per 72 and worst case would be all characters escaped.  If so, use Base64.
  40.     For lChar = 0 To UBound(bIn)
  41.         With m_EncoderTable(bIn(lChar))
  42.             If .IsSingleChar Then             'Normal processing
  43.                 bOut(lPos) = .lChar
  44.                 lPos += 1
  45.                 lLine += 1
  46.             ElseIf .CheckLine0 Then           'Test for column one, escape if in that col.
  47.                 If lLine <> 0 Then
  48.                     bOut(lPos) = .lChar
  49.                     lPos += 1
  50.                     lLine += 1
  51.                 Else
  52.                     bOut(lPos) = 61
  53.                     bOut(lPos + 1) = .Line0Char
  54.                     lPos += 2
  55.                     lLine += 2
  56.                 End If
  57.             Else                              'Critical char, needs to be escaped.
  58.                 bOut(lPos) = 61
  59.                 bOut(lPos + 1) = .lChar
  60.                 lPos += 2
  61.                 lLine += 2
  62.             End If
  63.         End With
  64.         If lLine >= 128 Then           'Add a vbCrLf
  65.             bOut(lPos) = 13
  66.             bOut(lPos + 1) = 10
  67.             lPos += 2
  68.             lLine = 0
  69.         End If
  70.     Next lChar
  71.  
  72.     ReDim Preserve bOut(lPos - 1)           'Truncate the unused portion of the buffer.
  73.     Return System.Text.Encoding.GetEncoding(1252).GetString(bOut)
  74. End Function