代码执行速度超过2000个小文件(~10-50 Kb)~1分钟。 Parallelizm = 5。
@arenaData =
EXTRACT col1, col2, col3
FROM @in
USING Extractors.Tsv(quoting : true, skipFirstNRows : 1, nullEscape : "\\N", encoding:Encoding.UTF8);
@res =
SELECT col1, col2, col3
FROM @arenaData;
OUTPUT @res
TO @out
USING Outputters.Csv();
但如果我改变这样的代码需要~1小时
@arenaData =
EXTRACT col1, col2, col3
FROM @in
USING Extractors.Tsv(quoting : true, skipFirstNRows : 1, nullEscape : "\\N", encoding:Encoding.UTF8);
@res =
SELECT
col1.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) AS col1_converted,
, col2, col3
FROM @arenaData;
OUTPUT @res
TO @out
USING Outputters.Csv();
为什么.NET调用这么慢?我需要将源CSV文件中的日期格式转换为“yyyy-MM-dd HH:mm:ss”?我怎样才能有效地做到这一点?
答案 0 :(得分:3)
很高兴听到你现在获得更好的表现!
您的作业使用在托管代码中执行的表达式运行超过2800个非常小的文件,而不是转换为C ++,因为U-SQL中的一些更常见的C#表达式是。
这会导致以下问题:
您可以使用一定数量的AU开始工作。然后每个AU启动一个YARN容器来执行您的部分工作。这意味着容器需要干净地初始化,这需要一些时间(您可以在顶点执行视图中将其视为创建时间)。现在这需要一些时间,如果您的顶点执行大量处理,那就不会有太大的开销。不幸的是,在你的情况下,小文件的处理速度非常快,因此开销很大。
如果顶点只执行我们将代码生成到C ++代码中的系统生成的代码,那么我们可以重用容器而不需要重新初始化时间。遗憾的是,由于潜在的工件被遗忘,我们无法重用使用托管运行时执行的一般用户代码。因此,在这种情况下,我们需要重新初始化容器,这需要花费时间(超过2800次)。
现在根据您的反馈,我们正在改进我们的重新初始化逻辑(如果您不使用内联C#表达式做任何事情,我们仍然可以重新初始化)。此外,一旦我们可以在单个顶点内处理多个小文件而不是每个顶点一个文件,它会变得更好。
您的解决方法是增加文件的大小,并且可能避免自定义代码(当然并不总是可能)在太多顶点中。