上一篇文章,我们通过实例比较了一下C#和Rust的性能表现,应该说在Release模式下面,Rust进行计算密集型的运算还是有些比较明显的优势的。那么,我们有没有可能,在C#中做一些快速应用开发,而一些核心的算法用Rust来实现呢?答案是可以的。

编写Rust代码

下面这段代码,保存在lib.rs文件中

  1. use std::thread;
  2.  
  3. #[no_mangle]
  4. pub extern fn process(){
  5. let handles :Vec<_> =(0..10).map(|_|{
  6. thread::spawn(||{
  7. let mut x= 0;
  8. for _ in (0..5_000_000){
  9. x+=1
  10. }
  11. x
  12. })
  13. }).collect();
  14.  
  15. for h in handles{
  16. println!("Thread finished with count={}",h.join().map_err(|_| "Could not join a thread!").unwrap());
  17. }
  18.  
  19. println!("done!");
  20. }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

这段代码的几个关键点在于

1.声明为pub,也就是说要让外部可以访问到

2.声明为extern,意思应该也是说希望外部可以访问

3.添加一个标记 #[no_mangle],这个开关据说是阻止编译器在编译的时候,重命名函数。我也还不是很理解,先照这么做吧

其他部分就是标准的Rust代码了

生成Rust的动态链接库

默认情况下,Rust编译的库叫做静态链接库,如果我们需要编译动态链接库的话,需要在Cargo.toml文件中定义

然后,运行cargo build -- release命令生成动态链接库(dll)

我们在输出目录中,可以看到一个countlib.dll 的动态链接库文件

在C#中使用这个动态链接库

你可以将countlib.dll放在C#编译输出目录的根目录下面

  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Diagnostics;
  4. using System.Threading;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace ConsoleApplication1
  8. {
  9. class Program
  10. {
  11.  
  12. [DllImport("countlib.dll",CallingConvention= CallingConvention.Cdecl)]
  13. public static extern void process();
  14.  
  15. static void Main(string[] args)
  16. {
  17. Stopwatch watch = new Stopwatch();
  18. watch.Start();
  19.  
  20. //Parallel.For(0, 10, i =>
  21. //{
  22. // var x = 0;
  23. // for (int j = 0; j< 5000000; j++)
  24. // {
  25. // x += 1;
  26. // }
  27. // Console.WriteLine("线程:{0} 完成计数",Thread.CurrentThread.ManagedThreadId);
  28. //});
  29.  
  30. process();//调用Rust里面的程序process进行计算
  31.  
  32. watch.Stop();
  33. Console.WriteLine("耗时:{0}秒", watch.Elapsed.TotalSeconds);
  34. Console.Read();
  35. }
  36. }
  37.  
  38. }
  1.  
  1. Debug模式下面的耗时为 0.002秒(提升太明显了吧)
  1.  
  1. Release模式下面的耗时为0.002秒(基本上跟Debug模式不相上下,很神奇吗)
  1.  
  1. 那么,这个性能表现,几乎接近了直接使用Rust的性能,比原先用C#的方式提高了5倍。
  1.  
  1. 如此说来,计算密集型(尤其是需要用到多线程,多核)的任务,可以用Rust来编写,然后在C#中调用。
  1.  
  1. 【特别注意】
  1. cargo build默认情况下会根据当前计算机的配置进行编译,例如我是64位的计算机,那么编译出来的dll也是64位的,在C#中用的时候,就需要同样设置为64位,否则就会出现错误
  1.  

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

那么,cargo build是否可以指定对应的平台进行编译呢?可以通过指定 --target参数来实现,可用的值主要有

  1. x86_64-pc-windows-gnu
  1. i686-unknown-linux-gnu
  1. x86_64-unknown-linux-gnu
  1. 详细可以参考 http://doc.crates.io/manifest.html
  1. 我用下面这样用就可以编译一个通用的dll(既能用于32位,也能用于64位——采用WOW模式)
  1.  
  1. 其实这个编译选项,类似于我们在Visual Studio中使用Any CPU进行编译

Rust初步(六):在C#中使用Rust组件的更多相关文章

  1. Rust初步(四):在rust中处理时间

    这个看起来是一个很小的问题,我们如果是在.NET里面的话,很简单地可以直接使用System.DateTime.Now获取到当前时间,还可以进行各种不同的计算或者输出.但是这样一个问题,在rust里面, ...

  2. Rust初步(七):格式化

    在Rust中,如果要进行屏幕输出,或者写入到文件中,需要对数据进行格式化.这一篇总结一下它所支持的几种格式化方式. 这篇文章参考了以下官方文档,不过,按照我的风格,我还是会突出于C#语言的比较,这样可 ...

  3. Rust初步(五):Rust与C#性能比较

    我学习Rust的目的并不是说期望用它来取代掉现有的开发平台或语言.相反,我认为当前绝大部分研发团队,都不可能只用一个平台或者一个语言. 当组织增长,他们越来越依赖大量的编程语言.不同的编程语言有不同的 ...

  4. Rust初步(一):介绍

    最近在研究Rust这个新的语言.那么Rust是什么呢? Rust是一个注重安全与速度的现代系统编程语言,通过在没有垃圾回收的情况下保证内存安全来实现它的目标,这使它成为一个在很多其它语言不适合的用例中 ...

  5. 四十六、android中的Bitmap

    四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android ...

  6. python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍

    目录 python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍. 二丶列表,其它语言称为数组 1.列表的定义,以及语法 2.列表的使用,以及常用方法. 3.列表的常用操作 ...

  7. {Django基础六之ORM中的锁和事务}一 锁 二 事务

    Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 一 锁 行级锁 select_for_update(nowait=False, skip_locked=False) #注意必须用在 ...

  8. 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  9. 从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理

    从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理 作者:naaoveGI…    文章来源:naaoveGIS    点击数:1145    更新时间: ...

随机推荐

  1. Cannot connect to the Docker daemon. Is the docker daemon running on this host?

    解决方案 docker-machine restart&&eval "$(docker-machine env default)"&&docker- ...

  2. sql2000分享 批量建表dev_编号

    批量建表dev_3970000000014到dev_3970000000035 declare @i bigint declare @j int ) ) ) ) set @sql = '' set @ ...

  3. 通读SDWebImage①--总体梳理、下载和缓存

    本文目录 下载操作SDWebImageDownloaderOptions和下载过程实现 下载管理SDWebImageDownloader 缓存SDImageCache SDWebImageManage ...

  4. C#程序员经常用到的10个实用代码片段

    1 读取操作系统和CLR的版本 OperatingSystem os = System.Environment.OSVersion; Console.WriteLine(“Platform: {}”, ...

  5. Webform 上传图片加水印

    界面: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx ...

  6. iPhone6/6 Plus兩款大屏智能機

    蘋果終於順應時代潮流,於今年推出了iPhone6/6 Plus兩款大屏智能機.但很快就有人開始懷念老款iPhone的“一手掌控”,畢竟不是所有人都有一雙大手.不過近期就有傳言稱,蘋果將於明年重新推出一 ...

  7. Angular 1.x 升级到 Angular 2

    原项目用ng1.5写的,现在改成ng2.0了,踩了不少坑,不过都忘记了. 如果你也正好要做这个工作,正好看到这个文章,不妨参考下. AngularJs 1.x -> 2.0 ng-repeat ...

  8. 6.数组和Hash表

    当显示多条结果时,存储在变量中非常智能,变量类型会自动转换为一个数组. 在下面的例子中,使用GetType()可以看到$a变量已经不是我们常见的string或int类型,而是Object类型,使用-i ...

  9. Sort简单排序

    List<T> 类型排序: public List<ProductionMaterialModel> OrderBybom(List<ProductionMaterial ...

  10. ios获取左右眼图片景深图

    cv::Mat leftMat,rightMat,depthMapMat; UIImageToMat(leftImage, leftMat); UIImageToMat(rightImage, rig ...