Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
47cc8d57
F
fsharp
项目概览
dotNET Platform
/
fsharp
9 个月 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fsharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
47cc8d57
编写于
8月 25, 2023
作者:
K
kerams
提交者:
GitHub
8月 25, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimize pattern compilation (#15849)
* Optimize pattern compilation
上级
81c71553
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
59 addition
and
44 deletion
+59
-44
src/Compiler/Checking/PatternMatchCompilation.fs
src/Compiler/Checking/PatternMatchCompilation.fs
+37
-44
src/Compiler/Utilities/illib.fs
src/Compiler/Utilities/illib.fs
+17
-0
src/Compiler/Utilities/illib.fsi
src/Compiler/Utilities/illib.fsi
+5
-0
未找到文件。
src/Compiler/Checking/PatternMatchCompilation.fs
浏览文件 @
47cc8d57
...
...
@@ -23,6 +23,7 @@ open FSharp.Compiler.TypedTreeBasics
open
FSharp
.
Compiler
.
TypedTreeOps
open
FSharp
.
Compiler
.
TypedTreeOps
.
DebugPrint
open
FSharp
.
Compiler
.
TypeRelations
open
type
System
.
MemoryExtensions
exception
MatchIncomplete
of
bool
*
(
string
*
bool
)
option
*
range
exception
RuleNeverMatched
of
range
...
...
@@ -905,43 +906,38 @@ let rec layoutPat pat =
let
mkFrontiers
investigations
clauseNumber
=
investigations
|>
List
.
map
(
fun
(
actives
,
valMap
)
->
Frontier
(
clauseNumber
,
actives
,
valMap
))
let
singleFalseInvestigationPoint
=
[|
false
|]
// Search for pattern decision points that are decided "one at a time" - i.e. where there is no
// multi-way switching. For example partial active patterns
let
rec
investigationPoints
inpPat
=
seq
{
match
inpPat
with
|
TPat_query
((_,
_,
_,
_,
_,
apinfo
),
subPat
,
_)
->
yield
not
apinfo
.
IsTotal
yield
!
investigationPoints
subPat
|
TPat_isinst
(_,
_
tgtTy
,
subPatOpt
,
_)
->
yield
false
match
subPatOpt
with
|
None
->
()
|
Some
subPat
->
yield
!
investigationPoints
subPat
|
TPat_as
(
subPat
,
_,
_)
->
yield
!
investigationPoints
subPat
|
TPat_disjs
(
subPats
,
_)
|
TPat_conjs
(
subPats
,
_)
|
TPat_tuple
(_,
subPats
,
_,
_)
|
TPat_recd
(_,
_,
subPats
,
_)
->
for
subPat
in
subPats
do
yield
!
investigationPoints
subPat
|
TPat_exnconstr
(_,
subPats
,
_)
->
for
subPat
in
subPats
do
yield
!
investigationPoints
subPat
|
TPat_array
(
subPats
,
_,
_)
|
TPat_unioncase
(_,
_,
subPats
,
_)
->
yield
false
for
subPat
in
subPats
do
yield
!
investigationPoints
subPat
|
TPat_range
_
|
TPat_null
_
|
TPat_const
_
->
yield
false
|
TPat_wild
_
|
TPat_error
_
->
()
}
match
inpPat
with
|
TPat_query
((_,
_,
_,
_,
_,
apinfo
),
subPat
,
_)
->
Array
.
prepend
(
not
apinfo
.
IsTotal
)
(
investigationPoints
subPat
)
|
TPat_isinst
(_,
_
tgtTy
,
subPatOpt
,
_)
->
match
subPatOpt
with
|
None
->
singleFalseInvestigationPoint
|
Some
subPat
->
Array
.
prepend
false
(
investigationPoints
subPat
)
|
TPat_as
(
subPat
,
_,
_)
->
investigationPoints
subPat
|
TPat_disjs
(
subPats
,
_)
|
TPat_conjs
(
subPats
,
_)
|
TPat_tuple
(_,
subPats
,
_,
_)
|
TPat_exnconstr
(_,
subPats
,
_)
|
TPat_recd
(_,
_,
subPats
,
_)
->
subPats
|>
Seq
.
collect
investigationPoints
|>
Seq
.
toArray
|
TPat_array
(
subPats
,
_,
_)
|
TPat_unioncase
(_,
_,
subPats
,
_)
->
subPats
|>
Seq
.
collect
investigationPoints
|>
Seq
.
toArray
|>
Array
.
prepend
false
|
TPat_range
_
|
TPat_null
_
|
TPat_const
_
->
singleFalseInvestigationPoint
|
TPat_wild
_
|
TPat_error
_
->
[||]
let
rec
erasePartialPatterns
inpPat
=
match
inpPat
with
...
...
@@ -1740,16 +1736,13 @@ let CompilePatternBasic
// So disjunction alone isn't considered problematic, but in combination with 'when' patterns
let
isProblematicClause
(
clause
:
MatchClause
)
=
let
ips
=
seq
{
yield
!
investigationPoints
clause
.
Pattern
if
clause
.
GuardExpr
.
IsSome
then
yield
true
}
|>
Seq
.
toArray
let
ips
=
if
isPatternDisjunctive
clause
.
Pattern
then
Array
.
append
ips
ips
else
ips
// Look for multiple decision points.
// We don't mind about the last logical decision point
ips
.
Length
>
0
&&
Array
.
exists
id
ips
[
0
..
ips
.
Length
-
2
]
if
clause
.
GuardExpr
.
IsSome
then
isPatternDisjunctive
clause
.
Pattern
||
Array
.
exists
id
(
investigationPoints
clause
.
Pattern
)
else
// Look for multiple decision points.
// We don't mind about the last logical decision point
let
ips
=
investigationPoints
clause
.
Pattern
ips
.
Length
>
0
&&
Span
.
exists
id
(
ips
.
AsSpan
(
0
,
ips
.
Length
-
1
))
let
rec
CompilePattern
g
denv
amap
tcVal
infoReader
mExpr
mMatch
warnOnUnused
actionOnFailure
(
origInputVal
,
origInputValTypars
,
origInputExprOpt
)
(
clausesL
:
MatchClause
list
)
inputTy
resultTy
=
match
clausesL
with
...
...
src/Compiler/Utilities/illib.fs
浏览文件 @
47cc8d57
...
...
@@ -335,6 +335,12 @@ module Array =
let
endsWith
(
suffix
:
_[])
(
whole
:
_[])
=
isSubArray
suffix
whole
(
whole
.
Length
-
suffix
.
Length
)
let
prepend
item
(
array
:
'
T
[]
)
=
let
res
=
Array
.
zeroCreate
(
array
.
Length
+
1
)
res
[
0
]
<-
item
Array
.
blit
array
0
res
1
array
.
Length
res
module
Option
=
let
mapFold
f
s
opt
=
...
...
@@ -622,6 +628,17 @@ module ResizeArray =
// in order to prevent long-term storage of those values
chunkBySize
maxArrayItemCount
f
inp
module
Span
=
let
inline
exists
([<
InlineIfLambda
>]
predicate
:
'
T
->
bool
)
(
span
:
Span
<
'
T
>)
=
let
mutable
state
=
false
let
mutable
i
=
0
while
not
state
&&
i
<
span
.
Length
do
state
<-
predicate
span
[
i
]
i
<-
i
+
1
state
module
ValueOptionInternal
=
let
inline
ofOption
x
=
...
...
src/Compiler/Utilities/illib.fsi
浏览文件 @
47cc8d57
...
...
@@ -126,6 +126,8 @@ module internal Array =
/// Returns true if one array has trailing elements equal to another's.
val
endsWith
:
suffix
:
'
a
[]
->
whole
:
'
a
[]
->
bool
when
'
a
:
equality
val
prepend
:
item
:
'
T
->
array
:
'
T
[]
->
'
T
[]
module
internal
Option
=
val
mapFold
:
f
:
(
'
a
->
'
b
->
'
c
*
'
a
)
->
s
:
'
a
->
opt
:
'
b
option
->
'
c
option
*
'
a
...
...
@@ -225,6 +227,9 @@ module internal ResizeArray =
/// probability of smaller collections. Stop-the-world is still possible, just less likely.
val
mapToSmallArrayChunks
:
f
:
(
'
t
->
'
a
)
->
inp
:
ResizeArray
<
'
t
>
->
'
a
[][]
module
internal
Span
=
val
inline
exists
:
predicate
:
(
'
T
->
bool
)
->
span
:
Span
<
'
T
>
->
bool
module
internal
ValueOptionInternal
=
val
inline
ofOption
:
x
:
'
a
option
->
'
a
voption
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录