Foxtable(狐表)用户栏目专家坐堂 → 令人目瞪口呆的效率差别(有修正)


  共有48337人关注过本帖树形打印复制链接

主题:令人目瞪口呆的效率差别(有修正)

帅哥哟,离线,有人找我吗?
狐狸爸爸
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
令人目瞪口呆的效率差别(有修正)  发帖心情 Post By:2010/12/7 12:36:00 [显示全部帖子]

您无权查看精华帖子

[本帖被加为精华]
 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 14:35:00 [显示全部帖子]

以下是引用易服在2010-12-7 13:41:00的发言:

有一按钮“编号”:自觉效率不高,能优化?

Dim str As String
For Each dr As DataRow In DataTables("申请表").DataRows
    str = "[乡名] = '" & dr("乡名") & "'And [村名] = '" & dr("村名") & "' And [组别] = '" & dr("组别") & "'"
    str = str  & "And  [单位(个人)] = '" & dr("单位(个人)") & "'  And  [法定代表人] = '" & dr("法定代表人") & "' And [_Identify] < " & dr("_Identify")
    dr("宗地序号") = Format(Tables("申请表").Compute("Count(乡名)",str)+1,"00")
Next
Tables("申请表").Sort = "法定代表人 DESC" '降序排列

 

可以这么改改看看:

 

Dim str As String
Dim Dic As New Dictionary(of DataRow, String)
For Each dr As DataRow In DataTables("申请表").DataRows
    str = "[乡名] = '" & dr("乡名") & "'And [村名] = '" & dr("村名") & "' And [组别] = '" & dr("组别") & "'"
    str = str  & "And  [单位(个人)] = '" & dr("单位(个人)") & "'  And  [法定代表人] = '" & dr("法定代表人") & "' And [_Identify] < " & dr("_Identify")
    dic.Add(dr,Format(DataTables("申请表").Compute("Count(乡名)",str)+1,"00"))
Next
For dr As DataRow In dic.Keys
    dr("宗地序号") = dic(dr)
Next


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 15:02:00 [显示全部帖子]

这都看不出来吗,我手误而已, 应该是:

 

For Each dr As DataRow In dic.keys

 


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 15:04:00 [显示全部帖子]

看来不单单查询这样,遍历过程中,任何涉及到所有行的操作,例如查找和计算都如此,我将第一列和第二列改为整数型,下面两段代码效率同样相差几百倍:

 

普通的:

Dim v As Double
For Each dr As DataRow In DataTables("表A").DataRows
    v = DataTables("表A").Compute("Sum(第二列 )", "第二列 = " & dr("第一列"))
    dr("第四列") = v
Next

 

高效的,快了300倍:

Dim Dic As new Dictionary(of DataRow, Integer)
Dim v As Double
For Each dr As DataRow In DataTables("表A").DataRows
    v = DataTables("表A").Compute("Sum(第二列 )", "第二列 = " & dr("第一列"))
    dic.Add(dr, v) 
Next
For Each dr As DataRow In dic.Keys
    dr("第四列") = dic(dr)
Next


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 16:13:00 [显示全部帖子]

以下是引用易服在2010-12-7 15:59:00的发言:

两者几乎没什么差别,12740条记录用时原来代码1分48秒多,新代码1分46多,手按秒表计时有点误差。

 

有差别的,你改得不对而已。


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 17:14:00 [显示全部帖子]

下面这个文件,可以配合一楼的代码测试,注意每次测试都重新打开项目,不用保存:

 

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目22.table

[此贴子已经被作者于2010-12-7 23:21:44编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 22:09:00 [显示全部帖子]

Dictionary帮助中有的:

 

http://help.foxtable.com/topics/1945.htm

 


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 22:58:00 [显示全部帖子]

呵呵,其实真的没啥用的,一楼的问题,一般人也遇不到。

 


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 23:13:00 [显示全部帖子]

以下是引用hnaysx在2010-12-7 22:59:00的发言:
关键我这里测试不出来你所的200多秒

 

那就比较一下这两段吧

 

第一段:

 

Dim v As Double
For Each
dr As DataRow In DataTables("表A").DataRows
    v
= DataTables("表A").Compute("Count(第二列 )", "第二列 = " & dr("第一列"))
   
dr("第四列") = v

Next

 

第二段:

 

Dim Dic As new Dictionary(of DataRow, Integer)
Dim
v As Double

For Each
dr As DataRow In DataTables("表A").DataRows
    v = DataTables("表A").Compute("Count(第二列 )", "第二列 = " & dr("第一列"))

    dic
.Add(dr, v
)
Next
For Each
dr As DataRow In dic.
Keys
   
dr("第四列") = dic(dr
)
Next


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47511 积分:251479 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/12/7 23:53:00 [显示全部帖子]

其实这是ado.net的一个bug或不足,下面两段代码,和Foxtable没有关系,第二段还是比第一段快上百倍:

 

第一段:

 

Dim t As New Data.DataTable
Dim r As Data.DataRow
t.Columns.Add("第一列",Gettype(Integer))
t.Columns.Add("第二列",Gettype(Integer))
t.Columns.Add("第三列",Gettype(Boolean))
For i As Integer = 0 To 10000
    r = t.NewRow()
    r("第一列") = rand.Next(1,30000)
    r("第二列") = rand.Next(1,30000)
    t.Rows.Add(r)
Next
Dim tm As Date = Date.Now
For Each r In t.Rows
    If t.Select("第二列 = " & r("第一列")).Length > 0 Then
        r("第三列") = True
    Else
        r("第三列") = False
    End If
Next
output.show((Date.Now - tm).TotalSeconds)


 

第二段:

 

Dim t As New Data.DataTable
Dim r As Data.DataRow
Dim l1 As New List(of Data.DataRow)
Dim l2 As New List(of Data.DataRow)
t.Columns.Add("第一列",Gettype(Integer))
t.Columns.Add("第二列",Gettype(Integer))
t.Columns.Add("第三列",Gettype(Boolean))
For i As Integer = 0 To 10000
    r = t.NewRow()
    r("第一列") = rand.Next(1,30000)
    r("第二列") = rand.Next(1,30000)
    t.Rows.Add(r)
Next
Dim tm As Date = Date.Now
For Each r In t.Rows
    If t.Select("第二列 = " & r("第一列")).Length > 0 Then
        l1.Add(r)     
    Else
        l2.Add(r)
    End If
Next
For Each r In l1
    r("第三列") = True
Next
For Each r In l2
    r("第三列") = False
Next
output.show((Date.Now - tm).TotalSeconds)

 

[此贴子已经被作者于2010-12-7 23:52:52编辑过]

 回到顶部
总数 32 1 2 3 4 下一页