Monday, March 7, 2016

TAP is almost the same as TPL for ComputeBound task

my previous post showed that logging to disk using async vs, buffer (Blocking collection, ring buffer) has significant impact on UI Processing. i.e. main thread spend 80% doing UI Processing vs 1-40%.
The tool is VS 2013/2015 Concurrency Visualizer.

But if the task is Compute Bound (Fabonacci) then TAP (task-based async pattern) vs TPL (Task Parallel Library) show no difference ---- Visualizer show both have main thread doing UI process 100%

here is the code in a WPF code-behind with a button and a Label L, offloading compute to TAP or TPL.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //TPL_ComputeBound();
            TAP_ComputeBound();
        }

        void TPL_ComputeBound()
        {
            // will return from thread pool in ContinueWith
            long ret = 0;
            var task = Task.Run(() => ret = Fibonacci(n))
                .ContinueWith((t) => L.Content = ret, TaskScheduler.FromCurrentSynchronizationContext());
        }

        async void TAP_ComputeBound()  //asyn void breaks TPL/TAP workflow and should avoid
        {
            long ret = await ComputTask();
            L.Content = ret; // above blocks and return to UI main thread.
        }

        Task<long> ComputTask()
        {
            return Task.Run(() =>
            {
                return Fibonacci(n);
            }).ContinueWith((t) =>
            {
                return t.Result;
            });
        }

        long Fibonacci(long n)
        {
            unchecked
            {
                if (n == 1 || n == 2) return 1;
                return Fibonacci(n - 1) + Fibonacci(n - 2);
            }
        }
    }

No comments:

Post a Comment