测试场景
渲染一个卡片列表。三种方式
- 使用 json 模板渲染单个卡片,代码循环拼接列表
- 匿名 Object 循环拼接
- 纯模板渲染 List 生成
理论上, 模板替换 json 字符串是最快的,但是解析模板循环是最慢的。
模板渲染卡片
卡片模板
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"body": [
{
"altText": "${alt}",
"url": "${src}",
"type": "Image"
}
]
}
渲染逻辑
public static MessagingExtensionResponse CardLoop(IEnumerable<Img> images)
{
List<MessagingExtensionAttachment> attachments = images
.Select(
img =>
new MessagingExtensionAttachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JObject.Parse(CardTemplate.Expand(img)), // template
Preview = new Attachment() { }
}
)
.ToList();
return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult("grid", "result", attachments),
};
}
纯粹对象拼接
public static MessagingExtensionResponse PureObject(IEnumerable<Img> images)
{
List<MessagingExtensionAttachment> attachments = images
.Select(
img =>
new MessagingExtensionAttachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JObject.FromObject(
new
{
type = "AdaptiveCard",
body = new[]
{
new
{
altText = img.Alt,
url = img.Src,
type = "Image",
}
}
}
),
Preview = new ThumbnailCard()
{
Images = new List<CardImage>() { new CardImage(img.Src, img.Alt) }
}.ToAttachment()
}
)
.ToList();
return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult("grid", "result", attachments),
};
}
模板渲染列表
列表模板
{
"attachments": [
{
"$data": "${Imgs}",
"content": {
"type": "AdaptiveCard",
"body": [
{
"altText": "${alt}",
"url": "${src}",
"type": "Image"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
},
"contentType": "application/vnd.microsoft.card.adaptive",
"preview": {
"content": {
"images": [
{
"alt": "${alt}",
"url": "${src}"
}
]
},
"contentType": "application/vnd.microsoft.card.thumbnail"
}
}
],
"type": "result",
"attachmentLayout": "grid"
}
渲染逻辑
public static MessagingExtensionResponse FromTempateList(IEnumerable<Img> images)
{
var res = JObject.Parse(ListTemplate.Expand(new {Imgs:images}));
return new MessagingExtensionResponse
{
ComposeExtension = res.ToObject<MessagingExtensionResult>(),
};
}
Benchmark result
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19044.2006/21H2/November2021Update)
Intel Xeon CPU E5-1650 v4 3.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK=6.0.401
[Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT AVX2
DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT AVX2
Method | Mean | Error | StdDev |
---|---|---|---|
MixedObject | 26,301.74 μs | 496.889 μs | 531.666 μs |
PureObject | 38.26 μs | 0.759 μs | 1.267 μs |
PureTemplate | 58,808.77 μs | 1,139.154 μs | 1,481.222 μs |
结果上看,
- 纯Object的拼接新能上最佳(代码逻辑,效率最高)
- 直接模板渲染N张卡片的列表,比N慢一倍。(数组模板效率最低)