Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
c215a3b1
R
runtime
项目概览
dotNET Platform
/
runtime
12 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
c215a3b1
编写于
6月 10, 2020
作者:
B
Benjamin Bartels
提交者:
GitHub
6月 10, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added fast path to BinaryWriter.Write(string) (#37705)
上级
fe35942e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
70 addition
and
36 deletion
+70
-36
src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs
...ries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs
+70
-36
未找到文件。
src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs
浏览文件 @
c215a3b1
...
...
@@ -351,7 +351,7 @@ public virtual unsafe void Write(float value)
// Writes a length-prefixed string to this stream in the BinaryWriter's
// current Encoding. This method first writes the length of the string as
// a
four-byte unsigned integer
, and then writes that many characters
// a
n encoded unsigned integer with variable length
, and then writes that many characters
// to the stream.
//
public
virtual
unsafe
void
Write
(
string
value
)
...
...
@@ -359,8 +359,8 @@ public virtual unsafe void Write(string value)
if
(
value
==
null
)
throw
new
ArgumentNullException
(
nameof
(
value
));
int
len
=
_encoding
.
GetByteCount
(
value
);
Write7BitEncodedInt
(
len
);
int
totalBytes
=
_encoding
.
GetByteCount
(
value
);
Write7BitEncodedInt
(
totalBytes
);
if
(
_largeByteBuffer
==
null
)
{
...
...
@@ -368,54 +368,88 @@ public virtual unsafe void Write(string value)
_maxChars
=
_largeByteBuffer
.
Length
/
_encoding
.
GetMaxByteCount
(
1
);
}
if
(
len
<=
_largeByteBuffer
.
Length
)
if
(
totalBytes
<=
_largeByteBuffer
.
Length
)
{
_encoding
.
GetBytes
(
value
,
0
,
value
.
Length
,
_largeByteBuffer
,
0
);
OutStream
.
Write
(
_largeByteBuffer
,
0
,
len
);
_encoding
.
GetBytes
(
value
,
_largeByteBuffer
);
OutStream
.
Write
(
_largeByteBuffer
,
0
,
totalBytes
);
return
;
}
int
numLeft
=
value
.
Length
;
int
charStart
=
0
;
ReadOnlySpan
<
char
>
str
=
value
;
// The previous implementation had significant issues packing encoded
// characters efficiently into the byte buffer. This was due to the assumption,
// that every input character will take up the maximum possible size of a character in any given encoding,
// thus resulting in a lot of unused space within the byte buffer.
// However, in scenarios where the number of characters aligns perfectly with the buffer size the new
// implementation saw some performance regressions, therefore in such scenarios (ASCIIEncoding)
// work will be delegated to the previous implementation.
if
(
_encoding
.
GetType
()
==
typeof
(
UTF8Encoding
))
{
while
(
numLeft
>
0
)
{
_encoder
.
Convert
(
str
.
Slice
(
charStart
),
_largeByteBuffer
,
numLeft
<=
_maxChars
,
out
int
charCount
,
out
int
byteCount
,
out
bool
_
);
OutStream
.
Write
(
_largeByteBuffer
,
0
,
byteCount
);
charStart
+=
charCount
;
numLeft
-=
charCount
;
}
}
else
{
// Aggressively try to not allocate memory in this loop for
// runtime performance reasons. Use an Encoder to write out
// the string correctly (handling surrogates crossing buffer
// boundaries properly).
int
charStart
=
0
;
int
numLeft
=
value
.
Length
;
WriteWhenEncodingIsNotUtf8
(
value
,
totalBytes
);
}
}
private
unsafe
void
WriteWhenEncodingIsNotUtf8
(
string
value
,
int
len
)
{
// This method should only be called from BinaryWriter(string), which does a null-check
Debug
.
Assert
(
_largeByteBuffer
!=
null
);
int
numLeft
=
value
.
Length
;
int
charStart
=
0
;
// Aggressively try to not allocate memory in this loop for
// runtime performance reasons. Use an Encoder to write out
// the string correctly (handling surrogates crossing buffer
// boundaries properly).
#if DEBUG
int
totalBytes
=
0
;
int
totalBytes
=
0
;
#endif
while
(
numLeft
>
0
)
{
// Figure out how many chars to process this round.
int
charCount
=
(
numLeft
>
_maxChars
)
?
_maxChars
:
numLeft
;
int
byteLen
;
while
(
numLeft
>
0
)
{
// Figure out how many chars to process this round.
int
charCount
=
(
numLeft
>
_maxChars
)
?
_maxChars
:
numLeft
;
int
byteLen
;
checked
checked
{
if
(
charStart
<
0
||
charCount
<
0
||
charStart
>
value
.
Length
-
charCount
)
{
if
(
charStart
<
0
||
charCount
<
0
||
charStart
>
value
.
Length
-
charCount
)
{
throw
new
ArgumentOutOfRangeException
(
nameof
(
value
));
}
fixed
(
char
*
pChars
=
value
)
throw
new
ArgumentOutOfRangeException
(
nameof
(
value
));
}
fixed
(
char
*
pChars
=
value
)
{
fixed
(
byte
*
pBytes
=
&
_largeByteBuffer
[
0
]
)
{
fixed
(
byte
*
pBytes
=
&
_largeByteBuffer
[
0
])
{
byteLen
=
_encoder
.
GetBytes
(
pChars
+
charStart
,
charCount
,
pBytes
,
_largeByteBuffer
.
Length
,
charCount
==
numLeft
);
}
byteLen
=
_encoder
.
GetBytes
(
pChars
+
charStart
,
charCount
,
pBytes
,
_largeByteBuffer
.
Length
,
charCount
==
numLeft
);
}
}
#if DEBUG
totalBytes
+=
byteLen
;
Debug
.
Assert
(
totalBytes
<=
len
&&
byteLen
<=
_largeByteBuffer
.
Length
,
"BinaryWriter::Write(String) - More bytes encoded than expected!"
);
#endif
OutStream
.
Write
(
_largeByteBuffer
,
0
,
byteLen
);
charStart
+=
charCount
;
numLeft
-=
charCount
;
}
#if DEBUG
Debug
.
Assert
(
totalBytes
==
len
,
"BinaryWriter::Write(String) - Didn't write out all the bytes!"
);
totalBytes
+=
byteLen
;
Debug
.
Assert
(
totalBytes
<=
len
&&
byteLen
<=
_largeByteBuffer
.
Length
,
"BinaryWriter::Write(String) - More bytes encoded than expected!"
);
#endif
OutStream
.
Write
(
_largeByteBuffer
,
0
,
byteLen
);
charStart
+=
charCount
;
numLeft
-=
charCount
;
}
#if DEBUG
Debug
.
Assert
(
totalBytes
==
len
,
"BinaryWriter::Write(String) - Didn't write out all the bytes!"
);
#endif
}
public
virtual
void
Write
(
ReadOnlySpan
<
byte
>
buffer
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录