编组到复杂结构时提高性能

时间:2017-08-15 10:25:09

标签: vb.net

这是一个问题的后续跟进 .net file random access recoard locking

我已经能够使读取和编组工作正常,但是使用Fileget()时性能要慢得多。

有一些文章围绕,例如https://msdn.microsoft.com/en-us/library/ff647812.aspx

但遗憾的是,我们不得不使用非Blittable实体,并且他们没有提供有关如何提高性能的工作示例。

正在使用的当前代码示例:

<StructLayout(LayoutKind.Sequential, _ 
          CharSet:=Runtime.InteropServices.CharSet.Ansi, Pack:=1)>
Structure SALbchCX 'SAL555
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ1s As Char()   'H/D  
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
    <VBFixedString(8)> Public XJ2s As Char()   '
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
    <VBFixedString(8)> Public XJ3s As Char()   '
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)>
    Public XJ4 As Single
    Public XJ5 As Single
    <MarshalAs(UnmanagedType.R8, SizeConst:=8)>
    Public XJ6d As Double
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)>
    Public XJ7 As Single
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=61)>
    <VBFixedString(61)> Public XJ8s As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ8bs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ8cs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ8ds As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ8es As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJ8fs As Char()
    <MarshalAs(UnmanagedType.I4, SizeConst:=4)> 
    Public XJ8Al As Integer 
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)>
    Public XJ9 As Single
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=11)>
    <VBFixedString(11)> Public XJAs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
    <VBFixedString(30)> Public XJAAs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=9)>
    <VBFixedString(9)> Public XJBs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=35)>
    <VBFixedString(35)> Public XJBBs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=5)>
    <VBFixedString(5)> Public XJCs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=7)>
    <VBFixedString(7)> Public XJDs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
    <VBFixedString(8)> Public XJDas As Char() 
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)> 
    Public XJE As Single
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJFs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)>
    <VBFixedString(6)> Public XJGs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
    <VBFixedString(30)> Public XJHs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
    <VBFixedString(30)> Public XJIs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
    <VBFixedString(30)> Public XJJs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
    <VBFixedString(30)> Public XJKs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=35)>
    <VBFixedString(35)> Public XJKKs As Char()
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)>
    Public XJL As Single 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJMs As Char()
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)>
    <VBFixedString(2)> Public XJNs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=70)>
    <VBFixedString(70)> Public XJOs As Char() 
    <MarshalAs(UnmanagedType.R4, SizeConst:=4)>
    Public XJP As Single 
    Public XJQ As Single 
    Public XJR As Single 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
    <VBFixedString(1)> Public XJSs As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)>
    <VBFixedString(128)> Public XJTs As Char()
End Structure

....

Public SAL555 As SALbchCX 

....
Dim f5 As New FileStream(coUC, FileMode.Open, _
FileAccess.ReadWrite, FileShare.ReadWrite, Marshal.SizeOf(SAL555))


For X = 1 To 10
        GetBatchRec(X, f5) 'populates SAL555
Next X
....


Public Sub GetBatchRec(RecNumber As Integer, File As FileStream)

    Dim b() As Byte
    ReDim b(Marshal.SizeOf(SAL555) - 1)
    File.Seek((RecNumber - 1) * 600, SeekOrigin.Begin) 'Marshal.Size(SAL555)
    File.Read(b, 0, b.Length)
    Dim h = GCHandle.Alloc(b, GCHandleType.Pinned)
    SAL555 = Marshal.PtrToStructure(Of SALbchCX)(h.AddrOfPinnedObject())
    h.Free()

End Sub

我们正在使用ByValArray而不是ByValTStr,因为ByValTStr没有捕获字符串的最后一个字符,因为它期望结束返回char。我们使用SAL5.XJIs =新字符串(SAL555.XJIs)将char()复制到字符串,该字符串再次处理大约2ms的处理。

代码的主要两部分似乎占用了大部分时间。

File.Seek((RecNumber - 1) * 600, SeekOrigin.Begin) 'Marshal.Size(SAL555)
SAL555 = Marshal.PtrToStructure(Of SALbchCX)(h.AddrOfPinnedObject())

每个操作大约需要10毫秒,只需使用fileget()就可以使用大约8毫秒,所以我们在将char()复制到字符串之前就慢了两倍。

我正在跳跃,有人更好地了解如何将数据读取/编组到一个更复杂的结构中。

欢迎任何建议,谢谢Richard

仅供参考:忽略与&#34相关的答案;停止使用平面文件&#34;因为这不是现有选项:)

1 个答案:

答案 0 :(得分:0)

经过广泛的性能测试后,我们发现Marshaling的解决方案实际上比vb6 ported fileget()更快。

误导性的事情是,开发环境需要一个时间来运行循环但是当运行编译的EXE或visual studio内置的性能分析器时,编组的性能比fileget()好,我们也没有打过早锁定记录,赢/赢!!

每天学习新东西!

谢谢,理查德。