WinRT开发语言的功能和效率

WinRT开发有着多种选择性,就编程语言这一点就表现的很突出;这里就这一点 深入展开,探讨在WinRT开发之初如何依据各 个编程语言的特性、功能和效率来对 产品的技术方向做出选择。

这里我选择运行计算复杂度较高的算法作为测试方法,虽然不能代表全部,但 是很大程度上展示大家平时开发过程中所面临的常见场景 和问题。考虑到演示和 理解,就选择了查找100000以内的所有素数的个数的算法作为演示。另外也顺带演 示如何在WinRT下实现多编程语言和技 术之间的协作吧。

关于基本知识和算法吧详细的说明,请自行搜索各大引擎吧(关键 词:prime、素数),这里我就列举在各个语言下我的简单实现吧,其中包括使用 普通算法和并 行计算的两个版本。

第一部分,从目前.NET主流来看吧,以C# 为例,普通版本,这个没什么多说的,就是从前往后看某个数是不是素数:

private static int 
CountingInternal(int n)
{
     var numprimes = 1;
     for (var i = 3; i <= n; i += 2)
     {
         var isPrime = true;
         var limit = Math.Ceiling(Math.Sqrt(i)) + 1;
         for (var j = 3; j < limit; j += 2)
         {
             if (i%j == 0)
             {
                 isPrime = false;
                 break;
             }
         }
         if (isPrime)
         {
             numprimes++;
         }
     }
     return numprimes;
}

并行版本稍微复杂一点点,选择Parallel.For来并行执行一个从1至n/2的并行 循环(我这里偷懒了一下,没有处理奇 偶数的情况,因为我的调用时传入的都是 偶数),发现是素数,使用Interlocked辅助方法给计数增加1。

private static int 
CountingParallel(int n)
{
     var numprimes = 1;
     Parallel.For(1, n/2, i =>
     {
         if (IsPrime(i*2 + 1))
         {
              Interlocked.Increment(ref numprimes);
         }
     });
     return numprimes;
}

public static bool IsPrime(int n)
{
     if (n%2 == 0)
         return false;
     var limit = (int) (Math.Ceiling(Math.Sqrt(n)) + 1);
     for (var i = 3; i < limit; i += 2)
     {
         if (n%i == 0)
         {
             return false;
         }
     }
     return true;
}

第一种场景,直接嵌入算法到C# WinRT App工程,执行结果如下(单位毫 秒):

执行次数

1(启动)

2

3

4

5

普通

14.0299

9.0005

9.1825

8.0021

11.0181

并行

6.0008

2.0004

2.9993

2.0014

3.999

第二种场景,将C#算法包装在一个类库里(注意 是CLR类库,只能在C#/VB直接通用),在C# WinRT App工程中调用这个类库,执行 结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

12.0299

9.0019

10.003

9.0014

9.00017

并行

6.0008

2

3.0003

2.9997

1.9995

第三种场景,将C#算法包装到一个Windows Runtime Component(WRC)中,在C# WinRT App工程中调用这个WRC类库,执行结 果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

11.9904

9.0032

9

9。0028

9.00149

并行

6.0008

1.9817

1.9985

1.9993

2

第四种场景,将C#算法包装到一个Windows Runtime Component(WRC)中,在WinJS App工程中调用这个WRC类库,执行结果如 下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

11

9

8

9

8

并行

4

1

1

3

2

小结:以上是从.NET角度来进行的比较,很容易 看出第一次CLR加载在这里性能损耗表现的很明显,完成加载之后性能将稳定在一 定范 围内波动;另外,并行计算在纯算法的应用中有很明显的性能优势。

第二部分,接下来我们回归Native环境,这里我 依然使用普通和并行计算两种来尝试,普通的依然没什么可说的(实际上和C#的没 区 别,除了关键字不一样)。

static int CountingInternal(int n)
{
     auto numprimes = 1;
     for (auto i = 3; i <= n; i += 2)
     {
         auto isPrime = true;
         auto limit = ceil(sqrt(i)) + 1;

         for (auto j = 3; j < limit; j += 2)
         {
             if (i%j == 0)
             {
                 isPrime = false;
                 break;
             }
         }

         if (isPrime)
         {
             numprimes++;
         }
     }
     return numprimes;
}

并行版本,需要注意的是C++ lambda的传值 和作用域问题,其他的和C#的没区别:

static bool IsPrime(int n)
{
     if (n%2 == 0)
         return false;
     auto limit = (int) (ceil(sqrt(n)) + 1);
     for(auto i=3; i<limit; i+=2)
     {
         if(n%i == 0)
         {
             return false;
         }
     }
     return true;
}

static int CountingParallel(int n)
{
     auto numprimes = 1;
     parallel_for(1, n/2, [&](int i)
     {
         if(IsPrime(i*2+1))
         {
             InterlockedIncrement((volatile unsigned long*)&numprimes);
         }
     });
     return numprimes;
}

第一种场景,直接将C++算法放到C++ WinRT App 中使用,执行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

8.0019

7.9991

8.0209

8.9843

8.0181

并行

1.9794

1.998

1.9994

1.984

2.0003

第二种场景,将C++算法包装在DLL中,在C++ WinRT App中使用,执行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

9

9

9

8

9

并行

3

2

3

2

2

第三种场景,将C++算法包装在动态连接库Dll中,在C# WinRT App中通过 PInvoke来调用,执行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

9

9

8

9

9

并行

3

2

3

2

3

第四种场景,将C++算法包装在静态链接库Lib中,在C++ WinRT App中调用,执 行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

8

8

8

9

9

并行

2

3

3

2

3

第五种场景,将C++算法包装在Windows Runtime Component(WRC)中,在C# WinRT App中调用,执行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

8.0014

8.0191

8.0293

8.0019

9.0291

并行

1.9994

1.9999

1.998

1.9994

2.99982

第六种场景,将Windows Runtime Component(WRC)中,在WinJS App中调用, 执行结果如下(单位毫秒):

执行次数

1(启动)

2

3

4

5

普通

9

8

9

8

8

并行

2

2

3

2

3

第七种场景是将C++算法包装在Windows Runtime Library(WRL,基于COM的底 层开发)中,然后在任何一种WinRT App中调用,可以预见这是一种很强大的方 式,但同时也是最费解的一种方式,我成功的包装了普通算法的COM版,但是尝试 了很长时间不能成功实现并行运算 的版本,也就放弃在这里展示了,如果你知道 如何在WRL中实现并行计算并返回 IAsyncOperation<T>,请不吝赐教。 

小结:基于C++的实现在适用性、稳定性和执行效率上无可挑剔,如果对于所有 细节(包括第一次启动)的效率考虑,C++是优先 的;如果考虑到C++的复杂度, 如果项目对性能要求可以适当放松但对进度要求很高的时候,选择CLR会比较容易 控制的;如果原来已有的Web项目 向WinRT迁移,那么前段展示则可以考虑使用 WinJS+HTML来实现,后台算法根据需要选择C++或者CLR。

第三部分,如果所有的算法全部运行在 JavaScript中,那么其性能如何呢?这里我先买个关子,留待你自己去探究和发 掘。

总结,WinRT在编程语言的选择性上有着非常好的 灵活性,在做选择的时候需要充分考虑自己的要求,比如性能、比如工期、比如经 验等 等。对于全新项目,在有经验的情况下,追求极致性能的首先首当其冲是 C++,如果考虑到经验和掌控,可以选择使用C++做底层,选择相对容易上手 的 C#/VB或者HTML+JS做界面的方法;如果项目工期要求很紧,或者从老系统迁移,那 么这时候更多的考虑是使用已有资源,直到性能瓶颈的时 候才采取措 施——以C++重写性能瓶颈来解决,当然,如果没有C++经验,也可以考 虑使用C#/VB来 实现WRC以包装核心逻辑,从而提升运行效率。目前已有部分软件支持WinRT,Spread WinRT 就是其中之一。它可以将 Microsoft Excel 的强大功能嵌入到 Windows 8 商店应用程序中,使用丰富的内嵌数据可视化功能展现核心数据和分析结果。

附以上测试源代码和测试工程,点击这里下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯大讲堂的专栏

如何为红包提供稳定支付体验

腾讯大讲堂隆重推出【100亿次的挑战】系列海量服务之道2.0讲座,覆盖技术、产品、项目管理、支撑、支付5个维度。第一场【技术篇】3000名鹅厂员工参与,场面火爆...

258100
来自专栏walterlv - 吕毅的博客

极限压缩 PNG

2017-11-29 12:17

17820
来自专栏人称T客

微软何时不再“阳萎” 看Nadella上任一年后憋了哪些大招

微软新任CEO Satya Nadella去年上任时,祭出“移动至上,云端优先”(mobile first and cloud first)的新政策,至今抛出了...

39750
来自专栏申龙斌的程序人生

搞定GTD - 掌控流程之三:组织整理

在明确意义那一步,只能去掉没有意义的项目和事情,在这一步才是GTD最复杂和最核心的流程,有人将第二步和第三步合在一起。对于OmniFocus来说,经过这个步骤后...

34990
来自专栏申龙斌的程序人生

搞定GTD - 总体流程图

掌握了第一步的捕捉流程,就要进入下一步流程了,但不要着急,此时先要对整个GTD的总体流程图做个大概了解,最经典的还是《搞定》书中原版的这张流程图了,网上有些人根...

543140
来自专栏IT派

2018,程序员要搭配这40条编程箴言!!!

IT派 - {技术青年圈} 持续关注互联网、大数据、人工智能领域 1、重构是程序员的主力技能。 2、工作日志能提升脑容量。 3、先用profiler调查,才有...

35950
来自专栏ThoughtWorks

Build 2016:细数给开发者的福利 | TW洞见

今日洞见 文章作者/配图来自ThoughtWorks:陈计节。 本文所有内容,包括文字、图片和音视频资料,版权均属ThoughtWorks公司所有,任何媒体、网...

317110
来自专栏技术翻译

程序员必知的10个工具!

每个程序员或软件开发人员都必须对源代码管理存储库有很好的了解,因为你需要每天签入、签出代码。而且,要成为一个更好的开发人员,还应该了解诸如分支和合并之类的高级概...

1.1K00
来自专栏SDNLAB

解决方案提供商关注的5大顶级IoT网关

物联网网关 尽管有了数据分析工具,云计算和连接的设备仍然是构成物联网产品的关键,但网关也至关重要。 ? 网关具备设备连通性、协议转换、数据过滤和处理以及安全性等...

31530
来自专栏我是攻城师

2015年需要了解的前端框架和语言

43970

扫码关注云+社区

领取腾讯云代金券