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:
'Values for yEnc Encoder Public Structure EncoderValues Public lChar As Byte Public IsSingleChar As Boolean Public CheckLine0 As Boolean Public Line0Char As Byte End Structure Public m_EncoderTable(255) As EncoderValues 'This is called in the Form_Load event. Public Sub SetupEncoder() Dim lngInput As Integer, bTest As Byte For lngInput = 0 To 255 With m_EncoderTable(lngInput) bTest = CByte((lngInput + 42) Mod 256) Select Case bTest Case 1 To 8, 11 To 12, 14 To 45, 47 To 60, 62 To 255 'Normal processing .lChar = bTest .IsSingleChar = True Case 46 'Test for column one, escape if in that col. .lChar = bTest .IsSingleChar = False .CheckLine0 = True .Line0Char = CByte((bTest + 64) Mod 256) Case Else 'Critical char, needs to be escaped. .lChar = CByte((bTest + 64) Mod 256) .IsSingleChar = False End Select End With Next lngInput End Sub Public Function EncodeData(ByVal bIn() As Byte) As String Dim bOut() As Byte, lChar As Integer, lPos As Integer, lLine As Integer ReDim bOut(UBound(bIn) * 2) 'Make the output buffer. Double size will almost always be enough. 2 extra 'chars per 72 and worst case would be all characters escaped. If so, use Base64. For lChar = 0 To UBound(bIn) With m_EncoderTable(bIn(lChar)) If .IsSingleChar Then 'Normal processing bOut(lPos) = .lChar lPos += 1 lLine += 1 ElseIf .CheckLine0 Then 'Test for column one, escape if in that col. If lLine <> 0 Then bOut(lPos) = .lChar lPos += 1 lLine += 1 Else bOut(lPos) = 61 bOut(lPos + 1) = .Line0Char lPos += 2 lLine += 2 End If Else 'Critical char, needs to be escaped. bOut(lPos) = 61 bOut(lPos + 1) = .lChar lPos += 2 lLine += 2 End If End With If lLine >= 128 Then 'Add a vbCrLf bOut(lPos) = 13 bOut(lPos + 1) = 10 lPos += 2 lLine = 0 End If Next lChar ReDim Preserve bOut(lPos - 1) 'Truncate the unused portion of the buffer. Return System.Text.Encoding.GetEncoding(1252).GetString(bOut) End Function




Reply With Quote