Skip to content

Instantly share code, notes, and snippets.

@Tocchann
Last active November 23, 2021 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tocchann/e2bef36bdd78809d9495e6c8cfbd5d1c to your computer and use it in GitHub Desktop.
Save Tocchann/e2bef36bdd78809d9495e6c8cfbd5d1c to your computer and use it in GitHub Desktop.
レンダリング丸ごと並列化
// 排他制御せずにレンダリングしてもらう(メモリイータータイプ)
private ImageSource CreateThumbnail( stirng filePath, Cube.Pdf.Page page )
{
using( var renderer = new DocumentRenderer( filePath ) )
using( var image = renderer.Render( page, page.Size ) )
using( var stream = new MemoryStream() )
{
image.Save( stream, ImageFormat.png );
stream.Seek( 0, SeekOrigin.Begin );
return BitmapFrame( stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad );
}
}
Task.Run( async ()=>
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var thumbnails = new ConcurrentBag<KeyValuePair<int, ImageSource>>();
var generateBitmapSource = new ActionBlock<KeyValuePair<int, Cube.Pdf.Page>>(
(kv) => thumbnails.Add( KeyValuePair.Create( kv.Key, CreateThumbnail( filename, kv.Value ) ),
new ExecutionDataflowBlockOptions { EnsureOrdered = false, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded }
);
foreach(var kv in pages.Select((page, index) => KeyValuePair.Create(index, page))) {
await generateBitmapSource.SendAsync(kv);
}
generateBitmapSource.Complete();
await generateBitmapSource.Completion;
foreach(var kv in thumbnails.OrderBy(kv => kv.Key)) {
vm.Thumbnails.Add(kv.Value);
}
stopwatch.Stop();
Debug.WriteLine("Pattern 3: " + stopwatch.ElapsedMilliseconds);
});
private ImageSource CreateThumbnail( DocumentRenderer renderer, Cube.Pdf.Page page )
{
using( var image = renderer.Render( page, page.Size ) )
using( var stream = new MemoryStream() )
{
image.Save( stream, ImageFormat.png );
stream.Seek( 0, SeekOrigin.Begin );
return BitmapFrame( stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad );
}
}
Task.Run( async ()=>
{
var stopwatch = new Stopwatch();
stopwatch.Start();
// rendererを使いまわす(キューに入れておくことで増えてもなければ作りあれば融通するという使い方をする
var rendererQueue = new ConcurrentQueue<DocumentRenderer>();
var thumbnails = new ConcurrentBag<KeyValuePair<int, ImageSource>>();
// タスク自体はコア数よりある程度多いほうが効率よく動く
var parallelCount = Environment.ProcessorCount * 2;
var generateBitmapSource = new ActionBlock<KeyValuePair<int, Cube.Pdf.Page>>(
(kv) =>
{
if( !rendererQueue.TryDeque( out var renderer ) ){
renderer = new DocumentRenderer( filename );
}
thumbnails.Add( KeyValuePair.Create( kv.Key, CreateThumbnail( renderer, kv.Value ) );
rendererQueue.Enqueue( renderer );
},
new ExecutionDataflowBlockOptions { EnsureOrdered = false, MaxDegreeOfParallelism = parallelCount }
);
foreach(var kv in pages.Select((page, index) => KeyValuePair.Create(index, page))) {
await generateBitmapSource.SendAsync(kv);
}
generateBitmapSource.Complete();
await generateBitmapSource.Completion;
foreach(var kv in thumbnails.OrderBy(kv => kv.Key)) {
vm.Thumbnails.Add(kv.Value);
}
stopwatch.Stop();
Debug.WriteLine("Pattern 3: " + stopwatch.ElapsedMilliseconds);
});
@Tocchann
Copy link
Author

MaxDegreeOfParallelismに与える数値を変更してなかったので修正。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment