1.4.3.1 并行化不可变程序

首先,让我们再看看清单 1.8,这是两段以函数方式写的游戏代码。在第一段,第二行用到了第一行的结果(运动后怪物的状态)。由于使用了不可变类,它没有给我们任何空间引入并行机制。

第二段代码的两行是独立的。我们刚才说过,用函数式编程,独立的程序部分能够并行。现在,我们发现,不可变性对于找出哪些部分程序是独立的,是一个好方法。即使我们不知道任何细节,也可以看出两个操作并行所能带来的变化,对源代码的改变是最小的:

var hitMonster = Task.Factory.StartNew(()=>

monster.HitByShooting(gunShot));

var hitPlayer = Task.Factory.StartNew(()=>

player.HitByShooting(gunShot));

我们唯一要做的,就是把这个计算用任务(Task)进行封装,这是并行扩展库(Parallel Extensions library)中的一个类型(我们将在第十四章详细讨论)少写代码并不是唯一的好处,更重要的是保证了代码的正确性。如果在命令式程序中进行类似的改变,必须仔细检查 HitByShooting 方法(和它调用的其他所有方法),找到所有访问可变状态的地方,加锁来保护代码,实现对共享状态的读写。在函数式编程中,一切都是不可变的,所以我们不需要添加任何锁。

本节示例使用了基于任务的并行化(task-based parallelism),是一种低级形式,第十四章我们将讨论三种方法,在下一节,将讨论另一种方法,它得益于声明式编程风格。

1.4.3.1 并行化不可变程序

时间: 2024-10-09 21:29:38

1.4.3.1 并行化不可变程序的相关文章

有用函数编程

<序> 感谢 关于本书 关于封面 第一部分 学习函数式思维 第一章 不同的思维 1.1 什么是函数式编程? 1.2 通往有用函数编程之路 1.3 用函数式编程提高生产力 1.3.1 函数范式 1.3.2 声明式编程风格 1.3.3 了解程序的执行 1.3.4 设计并发友好的应用程序 1.3.5 函数风格怎样形成代码 1.4 函数式编程演示样例 1.4.1 用声明式风格表达意图 1.4.1.1 用 LINQ 处理数据 1.4.1.2 用 XAML 描写叙述用户界面 1.4.1.3 声明式函数动画

容器和应用程序:扩展、重构或重建?

技术领域是不断变化的,因此,任何应用程序都可能在很短时间内面临过时甚至淘汰,更新换代的速度之快给人的感觉越来越强烈,我们如何使传统应用程序保持活力不落伍?工程师想的可能是从头开始重建传统应用程序,这与公司的业务目标和产品时间表通常是相悖的.如果现阶段正在运行的应用程序是正常工作的,这时候你很难找到正当而充分的理由让技术人员花六个月重写应用程序.代码债似乎注定意味着失败. 众所周知,产品开发向来都不是非黑即白那么简单,必须要权衡各方妥协折衷进行,虽然完全重写的可行性不大,但应用程序现代化的长远利益

GPU 编程入门到精通(四)之 GPU 程序优化

博主因为工作其中的须要,開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GPU 编程.因此在这里特地学习一下 GPU 上面的编程.有志同道合的小伙伴.欢迎一起交流和学习,我的邮箱: [email protected] . 使用的是自己的老古董笔记本上面的 Geforce 103m 显卡,尽管显卡相对于如今主流的系列已经很的弱.可是对于学习来说,还是能够用的.本系列博文也遵从由简单到复杂.记录自己学习的过程. 0. 文件夹 GPU 编程入门到精通

1.4.3 编写有效的并行程序

函数式编程可以更方便编写并行程序,这可能是你打算阅读这本书的原因.在本节,我们将用几个示例来演示函数式程序如何使并行更容易.在前两个示例中,我们将使用 Parallel Extensions to .NET(.NET 的并行扩展),这是微软的一项新技术,用于编写并行化的应用程序,是 .NET 4.0  的一部分.如你所料,ParallelExtensions to .NET 非常好地适合于函数式代码.我们并不更多地涉及细节,只想演示使函数式程序并行化,是极其简单,而更重要的是,比命令式代码更少出

Bash脚本实现批量作业并行化

在Linux下运行作业时, 经常会遇到以下情形: 有大量作业需要运行,完成每个作业所需要的时间也不是很长. 如果我们以串行方式来运行这些作业,可能要耗费较长的时间; 若采用并行方式运行则可以大大节约运行时间.再者, 目前的计算机绝大部分都是多核架构, 要想充分发挥它们的计算能力也需要并行化.总结网上看到的资料,利用Bash脚本,可以采用下面几种方法实现批量作业的并行化.注意,下面论述中将不会区分进程和线程,也不会区分并行和并发. 1. 采用GNU的paralle程序 parallel是GNU专门

【Spark深入学习 -12】Spark程序设计与企业级应用案例02

----本节内容------- 1.遗留问题答疑 1.1 典型问题解答 1.2 知识点回顾 2.Spark编程基础 2.1 Spark开发四部曲 2.2 RDD典型实例 2.3 非RDD典型实例 3.问题解答 4.参考资料 --------------------- 每一次答疑阶段,我都会站在老师的角度去思考一下,如果是我,我应该怎么回答,每每如此,不禁吓出一身冷汗.有些问题看答案确实挺容易的,但当自己作为一个答疑者去思考,可能不一样,因为快速确认一个答案的同时,你得否认很多的东西,脑海里闪过很

C/C++面试问题分类大汇总 ZZ 【C++】

http://www.mianwww.com/html/2014/05/21208.html 指针和引用的区别 指针指向一块内存,它的内容是指向内存的地址:引用是某内存的别名 引用使用是无需解引用,指针需解引用 引用不能为空,指针可以为空 引用在定义是被初始化一次,之后不可变:指针可变 程序为指针变量分配内存区域,而引用不需要分配内存区域 memcpy和strcpy的区别 memcpy用来内存拷贝的,它有指定的拷贝数据长度,他可以拷贝任何数据类型的对象 Strcpy它只能去拷贝字符串,它遇到’\

c++一些知識彙總

指针和引用的区别 指针指向一块内存,它的内容是指向内存的地址:引用是某内存的别名 引用使用是无需解引用,指针需解引用 引用不能为空,指针可以为空 引用在定义是被初始化一次,之后不可变:指针可变 程序为指针变量分配内存区域,而引用不需要分配内存区域 new和malloc的区别,free和delete的区别 malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存. 对于非内部数据类型的对象而言,光用maloc/free无法满足动态

Java 并发编程之性能和可伸缩性

对性能的思考 对于一个给定的操作,通常会缺乏某一种特定的资源限制它的性能,就像常说的短板理论,比如CPU时钟周期.内存.网络带宽.I/O带宽.数据库请求(这个应该是现在高并发的一个瓶颈).磁盘空间等等.当操作因为某种资源而受到限制时,我们就以资源+"密集型"命名这个操作,如CPU密集型,数据库密集型.. 相对于单线程来说,多线程在多个CPU存在时,能更好的发挥它的优势,不过如果是单核的情况下会花费更多的开销,比如.线程之间的协调,增加的上下文切换.线程的创建和销毁.以及线程的调度.如果