| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1020 人关注过本帖
标题:该如何加速?至少也要1秒100MB左右才合理吧~
只看楼主 加入收藏
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
结帖率:97.66%
收藏
已结贴  问题点数:20 回复次数:12 
该如何加速?至少也要1秒100MB左右才合理吧~
27.4MB的档案VB6要转5分多~再这样我要放弃VB6的了~改用C写了~
该如何加速?24.7MB只是测试档~实际上要考虑转 ?GB 级的档案~所以速度上实在不行~

图片附件: 游客没有浏览图片的权限,请 登录注册

速度是用API測的

程序代码:
Option Explicit

Dim FileName As String

Private Sub Command1_Click()
Dim S1 As Currency, S2 As Currency, f As Currency, t1 As Currency   '計時用

On Error GoTo ErrorHandling

    FileName = ""
    Dialog1.ShowOpen
    FileName = Dialog1.FileName
    
    If FileName <> "" Then
        FileName = Trim(FileName)
        Text1.Text = FileName
        Text1.ToolTipText = FileName
        
        Call QueryPerformanceFrequency(f)      '計時
        Call QueryPerformanceCounter(S1)       '計時
        
        Call UNIX2Dos(FileName)
'        Call TransFileFormat(FileName)
        
        Call QueryPerformanceCounter(S2)       '計時
        t1 = (S2 - S1) / f                     '計時
        
        MsgBox t1
        
    End If
    
Exit Sub

ErrorHandling:
    Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
    Resume Next
End Sub

Private Sub Form_Initialize()
    ErrorCount = 0: ReDim ErrorData(ErrorCount)
End Sub


程序代码:
Option Explicit

Public ErrorCount As Long
Public ErrorData() As String
Public iCount As Long

Public Declare Function QueryPerformanceCounter Lib "kernel32" (x As Currency) As Boolean
Public Declare Function QueryPerformanceFrequency Lib "kernel32" (x As Currency) As Boolean

Public Function UNIX2Dos(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString As Byte, newFileName As String

On Error GoTo ErrorHandling

    iCount = 0
    
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new.log"
    
    FileNum1 = FreeFile: FileNum2 = FreeFile + 1
    Open newFileName For Binary Access Write As #FileNum2
    Open FileName For Binary Access Read As #FileNum1
        Do While Not EOF(FileNum1)
            Get #FileNum1, , TempString
            
            If TempString = 10 Then
                Put #FileNum2, , CByte(Val(10))
                Put #FileNum2, , CByte(Val(13))
            Else
                Put #FileNum2, , CByte(Val(TempString))
            End If
            
            iCount = iCount + 1
            
            DoEvents
        Loop
    Close #FileNum1, #FileNum2
    
    UNIX2Dos = newFileName
    
Exit Function

ErrorHandling:
    Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
    Resume Next
End Function


[ 本帖最后由 wube 于 2011-5-20 21:47 编辑 ]
搜索更多相关主题的帖子: 测试 如何 左右 
2011-05-20 21:18
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:20 
这里,没有VB,用 记事本 修改了一下,你测试一下。

程序代码:
Public Function UNIX2Dos(FileName As String) As String

 Dim FileNum1 As Integer, FileNum2 As Integer, i As Long

 Dim TempString As Byte, newFileName As String

 
On Error GoTo ErrorHandling

 
    iCount = 0
     
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new.log"
     
    FileNum1 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
     FileNum2 = FreeFile                                  '前面产生的文件号,打开了文件后,就可以继续使用这个函数来取下一个未使用的文件号了。
                                                          '你前面使用 +1 的办法,在极端的情况下可能导致错误。
     Open FileName For Binary Access Read As #FileNum1
         Do While Not EOF(FileNum1)
             Get #FileNum1, , TempString
             
             If TempString = 10 Then
                 'Put #FileNum2, , CByte(Val(10))
                 'Put #FileNum2, , CByte(Val(13))
                 Put  #FileNum2, , vbcrlf                '使用常量 ,VBcrlf 就代表 chr(10)+chr(13) 
             Else
                 'Put #FileNum2, , CByte(Val(TempString))
                Put #FileNum2, , TempString              '这个变量本身是 BYTE 类型的,直接写入就可以,为什么要再用 函数转格式??
             End If
             
             iCount = iCount + 1
             
             DoEvents
         Loop
     Close #FileNum1, #FileNum2
     
    UNIX2Dos = newFileName
     
Exit Function

 
ErrorHandling:
     Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next

 End Function

授人于鱼,不如授人于渔
早已停用QQ了
2011-05-20 21:43
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
FileNum1 = FreeFile  'Error...

你寫倒反~我是FileNum2先開~所以要先Freefile~

CPU Load 50% ↑...内存使用量看不出~因为开的QQ本来就占很多~

图片附件: 游客没有浏览图片的权限,请 登录注册


更慢 = =

不要選我當版主
2011-05-20 21:59
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
二进位处理还是要用C才是王道~
这2天我先去把C搞出来~绝对会比VB6的快近百倍~因为C就是快~

以前处理STDF原稿用VB6的写(也是16进位转ACII码)~一个档案300MB的搞了快30分~
全部源码不变搬到VC去~只改语法~你猜花多久~10秒~

[ 本帖最后由 wube 于 2011-5-20 22:05 编辑 ]

不要選我當版主
2011-05-20 22:00
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:0 
VB处理字符流,还是有点慢。

CPU占用 50%,那说明,程序没有满载,问题我感觉应该是出在读 文件上面。
但VB读文件本来就是慢。。。。。。。。。。

你要面对 上GB 的文件,那就不能考虑一次性读入内存。
你测试一下这种的方法。
一次读 512字节到一个 byte 数组里。这个值可调,有可能 4096 (4k)会更性能更好一点. 4k是 NTFS 文件系统的分配块大小。
然后再来判断。感觉 这样的 IO 性能会更高一些。
这种方法需要对最后的尾数进行处理。

Con=文件字节数
for i=1 to con \ 512
    Get #FileNum1, , TempStrin()
    for j=0 to 512
       if tempstrin(j)=vblf then
             put .....  vbcrlf
       else
             put .... tempstrin(j)
       end if
   next j
next i
     input    con mod 512               '不太记得了,如果找不到,就重新定义 数组大小,以适应剩余的字节数。
                 '然后再同样判断,写入。


你发个文档过来,我测试一下。
40024605@
不过要明天才能有时间测试。

授人于鱼,不如授人于渔
早已停用QQ了
2011-05-20 22:19
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
回复 5楼 风吹过b
虽说是公司规定~是主要原因~不是我没诚意~不是我不发给你~而是公司档案全都是机密档案~而我又在研发部门~
要档案测很简单~我只是要转UNIX的DOS的~你随便电脑里找个100MB的的档案~
用UltraEdit的转存成UNIX的格式~再去用VB6的运行成DOS的格式也可以~

再说其实VB的不是开档慢~是他处理字串~人家C是直接用二进位在处理~VB的就偏先帮你转十进位~
在存的时候在帮你依需求转其他进位档~你试试看读取一个16进位档案进一个数组就知道了~
全都自动变成10进位~是比较人性化~但是就是这样花掉时间累积起来的~当然也许还有别的原因~
例如函式它有包好可以直接用的~很方便~但是实际上它包的是对于任何情况下都OK的~
所以使用者在使用时~他会多跑很多不需要的功能导致速度比较慢~这就是高阶语言比低阶语言效率低的原因~
但是高阶语言易懂易学是优点~要我学完VB中在去写C~我会想哭~

而且更悲惨的是~转档(UNIX->DOS)的这需求~只有VB需要~3个人在写这程式~一个用C~一个用LabView~
一个用VB~就只有VB会有这问题~现在另外两个都接近完工~我还在搞转格式~后续还有解析资料~依座标画图形~
依数值填表格之类的动作要做~我还在卡VB的读不出的UNIX档案~呵呵呵~
算是长见识了~VB的弱点~

我家没装QQ说~还在下~公司也是今天第一次装来试用看看而已~

[ 本帖最后由 wube 于 2011-5-20 23:19 编辑 ]

不要選我當版主
2011-05-20 23:03
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
别说我事前问问题都不先做功课~下面是UNIX2DOS的C源代码~

程序代码:
=============================== unix2dos.cpp ===============================

// converts Unix text files to DOS format by replacing \n with \r\n

#include <stdio.h>
#include <dir.h>
#include "readahead.h"

void main(int argc, char **argv)
{
  for (int i = 1; i < argc; i++)
  {
    readahead *f = new readahead(argv[i], 3);
    printf("%s:\n", argv[i]);
    if (!f->open())
    {
      fputs("Can't open file\n", stderr);
      continue;
    }
    FILE *t = tmpfile();
    while ((*f)[0] != EOF)
    {
      if ((*f)[0] == '\r' && (*f)[1] == '\n')
      {
        fputc('\n', t);
        f->advance(2);
      }
      else if ((*f)[0] == '\n')
      {
        fputc('\n', t);
        f->advance(1);
      }
      else
      {
        fputc((*f)[0], t);
        f->advance(1);
      }
    }
    delete f;
    rewind(t);
    FILE *ff = fopen(argv[i], "w");
    if (ff == NULL)
    {
      fputs("Can't modify file\n", stderr);
      continue;
    }
    int c;
    while ((c = fgetc(t)) != EOF)
      fputc(c, ff);
    fclose(t);
    fclose(ff);
  }
}

=============================== readahead.cpp ===============================

// File reading package with read-ahead

#include "readahead.h"

readahead::readahead(const char *filespecs, unsigned size, bool binary)
{
  psize = size;
  buffer = new int[psize];
  fp = fopen(filespecs, binary ? "rb" : "r");
  eof = fp == NULL;
  unsigned i;
  for (i = 0; i < psize; i++)
    buffer[i] = get();
}

readahead::~readahead()
{
  if (open())
  {
    delete [] buffer;
    fclose(fp);
    fp = NULL;
  }
}

void readahead::advance(unsigned count)
{
  while (count > 0)
  {
    unsigned i;
    for (i = 0; i < psize-1; i++)
      buffer[i] = buffer[i+1];
    buffer[i] = get();
    count--;
  }
}

int readahead::get(void)
{
  int c;
  if (eof)
    c = EOF;
  else
  {
    c = fgetc(fp);
    if (c == EOF)
      eof = true;
  }
  return c;
}

bool readahead::match(const char *s) const
{
  int i;
  for (i = 0; s[i] != 0; i++)
  {
    if (s[i] != (char) buffer[i])
      return false;
  }
  return true;
}

=============================== readahead.h   ===============================

#ifndef H__READAHEAD
#define H__READAHEAD

#include <stdio.h>

class readahead
{
  public:
    readahead(const char *filespecs, unsigned size, bool binary = false);
    ~readahead();
    bool open() const {return fp != NULL;}
    int operator [](int i) const {return buffer[i];}
    void advance(unsigned count = 1);
    bool match(const char *s) const;
  private:
    int *buffer;
    unsigned psize;
    FILE *fp;
    bool eof;
    int get(void);
};
#endif

不要選我當版主
2011-05-20 23:23
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册


BAS代码如下:
程序代码:
Option Explicit

Public ErrorCount As Long
Public ErrorData() As String
Public iCount As Long

Public Declare Function QueryPerformanceCounter Lib "kernel32" (x As Currency) As Boolean
Public Declare Function QueryPerformanceFrequency Lib "kernel32" (x As Currency) As Boolean

Public Function UNIX2Dos(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString As Byte, newFileName As String

On Error GoTo ErrorHandling

    iCount = 0
   
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new1.log"
   
    FileNum1 = FreeFile: FileNum2 = FreeFile + 1
    Open newFileName For Binary Access Write As #FileNum2
    Open FileName For Binary Access Read As #FileNum1
        Do While Not EOF(FileNum1)
            Get #FileNum1, , TempString
           
            If TempString = 10 Then
                Put #FileNum2, , CByte(Val(13))
                Put #FileNum2, , CByte(Val(10))
            Else
                Put #FileNum2, , CByte(Val(TempString))
            End If
           
            iCount = iCount + 1
           
            DoEvents
        Loop
    Close #FileNum1, #FileNum2
   
    UNIX2Dos = newFileName
   
Exit Function

ErrorHandling:
    'Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
    Resume Next
End Function



Public Function UNIX2Dos2(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString As Byte, newFileName As String

On Error GoTo ErrorHandling

    iCount = 0
    
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new2.log"
    
    FileNum2 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
    FileNum1 = FreeFile                                  '前面产生的文件号,打开了文件后,就可以继续使用这个函数来取下一个未使用的文件号了。
                                                          '你前面使用 +1 的办法,在极端的情况下可能导致错误。
     Open FileName For Binary Access Read As #FileNum1
         Do While Not EOF(FileNum1)
             Get #FileNum1, , TempString
            
             If TempString = 10 Then
                 'Put #FileNum2, , CByte(Val(10))
                 'Put #FileNum2, , CByte(Val(13))
                 Put #FileNum2, , vbCrLf                 '使用常量 ,VBcrlf 就代表 chr(10)+chr(13)
             Else
                 'Put #FileNum2, , CByte(Val(TempString))
                Put #FileNum2, , TempString              '这个变量本身是 BYTE 类型的,直接写入就可以,为什么要再用 函数转格式??
             End If
            
             iCount = iCount + 1
            
             DoEvents
         Loop
     Close #FileNum1, #FileNum2
    
    UNIX2Dos2 = newFileName
    
Exit Function

ErrorHandling:
     'Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next
End Function


Public Function UNIX2Dos3(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString(511) As Byte, newFileName As String
Dim j As Long

On Error GoTo ErrorHandling

    iCount = 0
    
    
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new3.log"
    
    FileNum2 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
    FileNum1 = FreeFile
     Open FileName For Binary Access Read As #FileNum1
    
        j = LOF(FileNum1)
         Do While Not EOF(FileNum1)
             'Get #FileNum1, , TempString
             'TempString = Input(512, #FileNum1)
            
             Get #FileNum1, , TempString
            
             For i = 0 To 511
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                If j = iCount Then Exit For
             Next i
             DoEvents
         Loop
     Close #FileNum1, #FileNum2
    
    UNIX2Dos3 = newFileName
    
Exit Function

ErrorHandling:
'     Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next
End Function


Public Function UNIX2Dos4(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString(4095) As Byte, newFileName As String
Dim j As Long

On Error GoTo ErrorHandling

    iCount = 0
    
    
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new4.log"
    
    FileNum2 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
    FileNum1 = FreeFile
     Open FileName For Binary Access Read As #FileNum1
        j = LOF(FileNum1)
         Do While Not EOF(FileNum1)
             'Get #FileNum1, , TempString
             'TempString = Input(512, #FileNum1)
            
             Get #FileNum1, , TempString
            
             For i = 0 To 4095
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                If j = iCount Then Exit For
             Next i
             DoEvents
         Loop
     Close #FileNum1, #FileNum2
    
    UNIX2Dos4 = newFileName
    
Exit Function

ErrorHandling:
'     Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next
End Function



授人于鱼,不如授人于渔
早已停用QQ了
2011-05-22 19:15
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
感谢高手协助先~
我再研究研究~这两天跑出去散心了~前辈要我不要24小时都泡在编程的世界里~
我太投入会疯掉~哈哈哈~

不要選我當版主
2011-05-22 22:30
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:0 
再次优化了后二种的处理代码,
同样这个测试文档,测试结果是:
5.9939
5.9925
感觉差别不是很大。稍有点效果。
测试文档的大小是:
642 KB (657,982 字节)
总体来说, VB 做这个事,效率很差,很差。
计算出来的速度是: 0.1047mb/秒
也就是 100K/秒 的速度。
不知道C 做这个事能达到多少速度。

过了几天才继续看。现在都没多大兴趣了。

程序代码:
Public Function UNIX2Dos3(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString(511) As Byte, newFileName As String
Dim j As Long

On Error GoTo ErrorHandling

    iCount = 0
   
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new3.log"

Dim o As Long
    FileNum2 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
    FileNum1 = FreeFile
     Open FileName For Binary Access Read As #FileNum1
    
        j = LOF(FileNum1)
         For o = 1 To j \ 512             '使用定次循环,减少循环内的一个判断,以节省运行时间,FOR 循环的条件只需要计算一次
         'Do While Not EOF(FileNum1)      '每次都需要引用函数计算条件,不使用
             'Get #FileNum1, , TempString
             'TempString = Input(512, #FileNum1)
            
             Get #FileNum1, , TempString
            
             For i = 0 To 511
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                'If j = iCount Then Exit For
             Next i
             DoEvents                                 '每个处理过程都有,就留着,可以对比
         'Loop
         Next o
        
             Get #FileNum1, , TempString
            
             For i = 0 To j Mod 512                   '处理剩下的字节
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                'If j = iCount Then Exit For
             Next i
             DoEvents
        
        
     Close #FileNum1, #FileNum2
    
    UNIX2Dos3 = newFileName
    
Exit Function

ErrorHandling:
'     Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next
End Function


Public Function UNIX2Dos4(FileName As String) As String
Dim FileNum1 As Integer, FileNum2 As Integer, i As Long
Dim TempString(4095) As Byte, newFileName As String
Dim j As Long

On Error GoTo ErrorHandling

    iCount = 0
    
    
    newFileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) & "_new4.log"
    
Dim o As Long

    FileNum2 = FreeFile
    Open newFileName For Binary Access Write As #FileNum2
    FileNum1 = FreeFile
     Open FileName For Binary Access Read As #FileNum1
        j = LOF(FileNum1)
        
        For o = 1 To j \ 4096
            
             Get #FileNum1, , TempString
            
             For i = 0 To 4095
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                'If j = iCount Then Exit For
             Next i
             DoEvents
        Next o
           
             Get #FileNum1, , TempString
            
             For i = 0 To j Mod 4096
                If TempString(i) = 10 Then
                    Put #FileNum2, , vbCrLf
                Else
                   Put #FileNum2, , TempString(i)
                End If
               
                iCount = iCount + 1
                'If j = iCount Then Exit For
             Next i
            

     Close #FileNum1, #FileNum2
    
    UNIX2Dos4 = newFileName
    
Exit Function

ErrorHandling:
'     Call ErrorWriteBuff(FileName, iCount, "TransformFile", Err.Number, Err.Description, "系統訊息")
     Resume Next
End Function

授人于鱼,不如授人于渔
早已停用QQ了
2011-05-25 13:07
快速回复:该如何加速?至少也要1秒100MB左右才合理吧~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.037450 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved