Java 与 F# 的并行程序处理对比

Azul System的Cliff Click博士是多核心JVM系统方面的专家,之前发表了一篇博文,首先比较了Java与C语言和C++的性能表现,但同时也讨论了C#和.NET。以下三个Cliffs博士的评论让人十分感兴趣:

在标题”Places where C/C++ beats Java for obvious reasons”下:

“值类型,例如复杂类型,在Java中需要一个类来支持”

“Value Types, such as a ‘Complex’ type require a full object in Java.” – Dr Cliff Click

Cliff忘记提及的是.NET同样提供值对象和比复数更加引人注意的humble hash table。

考虑一下以10,000,000个整数/单精度浮点数 填充hash表,这个任务可以使用Java来完成,如下:

package hashtablebenchmark;import java.util.HashMap;public class Main {    public static void main(String[] args) {        int n = 10000000;        for (int j=0; j<10; ++j) {            long startTime = System.currentTimeMillis();            HashMap hashtable = new HashMap(n);            for(int i=1; i<=n; ++i) {                hashtable.put(i, 1.0f / i);            }            System.out.println("m[100] = " + hashtable.get(100));            long time = System.currentTimeMillis() - startTime;            System.out.println("Took: " + time / 1e3 + "s");        }    }}

同样的程序在F#中不仅仅代码更短并且速度要快上17倍:

let n = 10000000let m = System.Collections.Generic.Dictionary(n)for i=1 to n do  m.[i] <- 1.0f / float32 iprintf "m[100] = %f\n" m.[100]

特别值得提及的是,Java初始化花费6.967s、稳态花费5.733s,而F#只用了0.414s。

实际上,F#通过这个测试后我们便想给它更大的工作量,而在这台4GB内存的机器上,Java不可能再做更多了。

在别处的评论,Cliff也这样写到Java:

“有非常好的多线程支持,并行程序设计在Java中很容易实现”

“Very Good Multi-Threading Support. Parallel programming is just easier in Java.” – Dr Cliff Click

之后又有:

“并非我如此关注C#而是…我认为JIT编码处理基本上比Java要慢”

“Not that I track C# all that closely but… I believe the JIT produces substantially slower code than Java” – Dr Cliff Click

允许我们在其他方面来证明,Computer Language Shootout软包含了一个格式良好的spectral-norm测试,最快的Java解决方案是一个173行的并行程序。其实现用F#来写只需要24行代码:

let A i j = 1.0 / float((i + j) * (i + j + 1) / 2 + i + 1)let inline mul A (u: _ []) (v: _ []) =  System.Threading.Tasks.Parallel.For(0, v.Length, fun i ->    let mutable vi = 0.0    for j = 0 to v.Length - 1 do      vi <- vi + A i j * u.[j]    v.[i] <- vi) |> ignorelet AtAu u v =  let w = Array.create (Array.length u) 0.0  mul (fun i j -> A i j) u w  mul (fun i j -> A j i) w vdo  let n = 5500  let u, v = Array.create n 1.0, Array.create n 0.0  for i = 0 to 9 do    AtAu u v    AtAu v u  let u, v = vector u, vector v  printf "%0.9f\n" (sqrt(Vector.dot u v / Vector.dot v v))

在Java代码中,大量的代码都是用来实现并行化。与之相反的是,F#在处理并行化上只用了两行代码。可见,并行程序设计在Java中可不是那么easy。

Java串行程序初始花费了12.722s稳态花费12.299s,而冷启动的F#只用了12.18s。在8核 2xE5405 2.0GHz Xeon的机器上,Java并行程序初始化花费1.839s稳态花费1.820s,而冷启动的F#并行程序只用了1.60s。事实证明,Java在每一个测试中都表明CLR的JIT并不是“处理基本上比Java更慢”

最后,Cliff并没有提到其他两个设计上(Java性能)的不足。首先,Java的泛型代码导致性能大幅下降,由于它使用了许多不必要的装箱操作。其次,JVM栈缺少尾部递归支持,这不仅仅对这个函数式编程的年代带来越来越多的障碍,而且唯一的一般解决方案也比需要的慢上10倍。

原文链接(需要FQ),OSChina原创编译

30 个用于杂志网站的 WordPress 主题

WordPress 已经形成了一个非常完善的生态链,为 WordPress 开发的各种插件、主题越来越丰富。本文介绍 30 个适用于杂志网站使用的 WordPress 主题,其中也包含一些收费的主题,制作非常精美。

免费的 WordPress 杂志主题 Snips

Snips

DotNews

DotNews

Render Magazine Theme

Render Magazine Theme

Polar Media Magazine WordPres Theme

Polar Media Magazine WordPres Theme

Oracle Mag Theme

Oracle Mag Theme

收费的 WordPress 杂志主题 Continuum – Magazine WordPress Theme

Continuum - Magazine WordPress Theme

Deadline – Premium WordPress News / Magazine Theme

Deadline

Avenue – A WordPress Magazine Theme

Avenue

Newscast 4 in 1 – WordPress Magazine and Blog

Newscast 4 in 1 - WordPress Magazine and Blog

BigFeature – WordPress Theme

BigFeature

Repro – Premium WordPress News / Magazine Theme

Repro - Premium WordPress News - Magazine Theme

theDawn Premium All-in-one WordPress Theme

theDawn Premium All-in-one WordPress Theme

Boulevard – A WordPress Magazine Theme

Boulevard - A WordPress Magazine Theme

Big City – Personal and Blog WordPress theme

Big City - Personal and Blog WordPress theme

Reaction WP : Responsive, Rugged, Bold

Reaction WP  Responsive Rugged

Super Skeleton WP: Responsive

Super Skeleton WP

London Live 3 In 1

London Live 3 In 1

Sprout – Magazine & Blog WordPress Theme

Sprout

Insignia – a Magazine / Community / Blog theme

Insignia

Mosaico – Unique Magazine Theme

Mosaico

Brewpper – A Premium & Dynamic News Theme

Brewpper

SwagMag – WordPress Magazine

SwagMag

Bangkok Press – Responsive, News

Bangkok Press

A – Personal Blog WordPress Theme

A - Personal Blog WordPress Theme

Backstreet – Blog & Magazine Theme

Backstreet - Blog & Magazine Theme

Retro Portfolio

Retro Portfolio

CookingPress

CookingPress

Strings Music and Art Magazine WordPress

Strings Music and Art Magazine WordPress

Website – responsive WordPress theme

Website - responsive WordPress theme

Advance WordPress Magazine

Advance WordPress Magazine

一个人是否能成为程序员是上天注定的

本文的作者 Swizec Teller

本文的作者 Swizec Teller

本文的作者是一个斯洛文尼亚共和国的独立程序员,自称是“戴帽子的黑客”,他使用Pascal、Delphi、 C/C++、Python,PHP,node.js等语言编程,他曾是著名的开源论坛phpBB的几个主要模块的开发人,先后为 hipstervision.org等五家公司网站的创始人或合作创始人,他目前的主要收入来自postme.me这个明信片网站。

程序员是一种特殊物种,好的程序员尤其是这样——在我们这个行当里很多人都试图把编程归入一种复杂的技术学科,但它实际上更倾向于一种艺术。它实际上更接近数学,音乐或电视剧《Firefly》里的Kaylee魔法。

好的程序员有一种特殊的直觉,一种天赋,这种天赋很难描述,更不容易得到。

几个星期前,@zidarsk8 跑到我这说“老大!我发现这样一个人!我还在在教他如何编程!但我发现他已经比我优秀了!他一个月前还不知道到什么是变量!太邪门了!“

他要我一定要在博客里写写这件事。为什么有些人就简单的学会了?他们有什么特殊之处?是否任何人都可以学会编程?还是只有有一定天分的人才能成为一个不错的(先别谈优秀)程序员?

我记得一年前曾辅导过一个高中的孩子。大概是担心考不过他的计算机课程,跑到我这来求助。一个月里,我把我知道的全教给他了,至少这些知识能让他通过考试。

快到月末的时候,他已经知道了所有关于循环、变量赋值的知识,甚至还明白了函数是一组能做某些事情的代码。我跟他父亲道别时说的话是“是的,他什么都知道了。只需要一些实践去掌握它们。”

Sheep

Image via Wikipedia

我不知道他是否考过了那个课程。如果他过了,那是老师的荣幸…而就我根据我高中时的记忆,老师们并非都那么幸运。并不是因为我不是个好老师我才这样说——我从很多受这个孩子推荐来到我这里的其他学生那里都收到了一封“谢谢你!出色的通过!耶!”的邮件——有些人很简单就是不能成为程序员。永远成不了程序员。更别说成为不错的程序员了。

不能编程的羊

Jeff Atwood在2006年曾写过关于把不能编程的山羊从能编程的绵羊中挑出来的文章,里面提到过一项研究,这些研究声称找到了一种能预测一个人将来的编程能力的测试。

测试非常的简单:

a = 5b = 20a = b现在a和b的值是什么?

有很多像这样的问题。只有44%学生的大脑里养成了固定的赋值思维模型——包括有些理解甚至是错误的。余下的人都答错了,或者是没有答。

更糟糕的是,在一个学期的编程学习后,这个比例没有任何变化。只有44%的理解了赋值的过程。

很显然,有些人就是学不会。

我想可能还有个更简单的测试 ->

Passion (novel)

Image via Wikipedia

热情

有时候,当你给一个有上进心的年轻心灵(任何愿意学习编程的人,年龄不是问题)两种工具和一个难题。他会使用这两种工具创造出4种工具。他会搜索互联网,发现更多的工具…很快,他有了20种工具,请问你还让我解决什么问题?

这就是热情!

心无杂念的对编程的热情。没有问题需要解决时仍然对编程入迷,甚至兴奋。甚至把解决一个已知的问题也当作一次普通的练习…这就是卓越之处。

多大岁数才开始学习编程,这并不重要——很多研究显示,在我们这个世界里,编程的工龄并不是水平的指示符——重要的是你对这个行业有个热情的心。

因为,一旦有了热情,你就拥有了所有其它的一切。

[本文英文原文链接:Programmers are born not made ]

Windows Phone Tango 功能演示视频

我们之前已经知道即将发布的Tango带来的新功能以及限制,国外的Windows Phone Hacker团队今天为我们带了一个Tango 功能演示视频,包含新的状态栏图标,改进的彩信功能等等,他们同时还发布了一个解锁版的模拟器提供下载(解锁版的模拟器可以支持大多数的任务): Tango演示视频

我们之前已经知道即将发布的Tango带来的新功能以及限制,国外的Windows Phone Hacker团队今天为我们带了一个Tango 功能演示视频,包含新的状态栏图标,改进的彩信功能等等,他们同时还发布了一个解锁版的模拟器提供下载(解锁版的模拟器可以支持大多数的任务):

演示视频:

模拟器下载地址1:ftp://[email protected]/tangoemulator.zip
模拟器下载地址2:http://www.crocko.com/2EAB73BF5BD343F1967E7E5546512055/tangoemulator.zip
模拟器下载地址3:https://rapidshare.com/files/1778895253/tangoemulator.zip

我痛恨 Git 的 10 个理由

Git 是一个源代码版本控制系统,正在迅速成为开源项目的标准。它有一个强大的分布式模型,允许高级用户用分支来处理各种棘手的问题和改写历史记录。但是,要学习 Git 是需要付出更多的努力,让人不爽的命令行接口以及 Git 是如此的忽视它的使用者。

下面是我为什么如此痛恨 Git 的 10 个理由:

1. 复杂的信息模型

Git 的信息模型是很复杂的,而且你必须对他们都很了解。在这个方面上你看看 Subversion:有文件、工作目录、资源库、版本、分支和标签。你需要了解的就是这些东西,实际上,分支、标签和文件你已经了解,但如果使用 Git ,你拥有更多的概念需要了解:文件、工作树、索引、本地资源库、远程资源库、远程、提交、treeishes、分支和 stash。你需要了解比 Subversion 更多得多的知识点。

2. 让人抓狂的命令行语法

Git 的命令行语法完全是随意的而且不一致,例如 git pull 基本上跟 git merge 和 git fetch 一样,git branch 和 git checkout 合并就变成 git checkout -b,git reset 命令的不同参数做的事情完全不一样,指定文件名后命令的语义完全不同等等。

而最为壮观的就是 git am 命令了,据我所知,这是因为 Linus 在当年某个晚上为了解决通过电子邮件阅读补丁而使用的不同的补丁语法,特别是在邮件的标题上。

3. 蹩脚、让人费解的文档

说起 Git 的这个文档,我唯一想说的就是“操”。他们是为计算机科学家在写文档,而不是用户。在这里举个例子:

git-push – Update remote refs along with associated objects

如果是针对用户而言,应该描述为:

git-push – Upload changes from your local repository into a remote repository

另外一个例子:

git-rebase – Forward-port local commits to the updated upstream head

翻译: git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node

4. 信息模型的扩散

刚才我在第一点提到的 Git 的信息模型是非常复杂的,而且还想癌细胞一样一直在扩散,当然一直在使用 Git ,就会不断的冒出各种新的概念,例如 refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces 之类的。

5. 漏洞百出的抽象

Git 包含太多不是抽象的抽象,在定义用户接口和实现上经常没有任何区别,这是可以理解的,对一个高级用户来说他需要了解一些功能的具体实现,以掌握各个命令的微妙之处。但大量的内部细节对初学者来说简直是噩梦。有这么一个说法,关于水暖器材和瓷器,但你必须成为一个水暖工才能知道器材如何安装在瓷器上。

很多人对我的抱怨予以回应说:你无需使用所有的命令,你可以向 Subversion 一样来使用 Git。这是狡辩,就好比是告诉一个老奶奶说高速公路并不可怕,她可以在高速路上靠左边的快车道上以时速 20 公里爬行,一样的道理。Git 并没有提供任何有用的子集,每个命令都会连带着对其他命令的要求,很简单的动作经常需要很复杂的动作来撤销或者改进。

下面是一个 Github 项目维护者的一些善意的建议:

  1. 在分支和 master 上寻找合并的基准: ‘git merge-base master yourbranch’
  2. 假设你已经提交了更改记录,从对你的提交重新基准化到合并准,然后创建一个新分支
  3. git rebase –onto <basecommit> HEAD~1 HEAD
  4. git checkout -b my-new-branch
  5. 检出你的 ruggedisation 分支,然后移除提交: ‘git reset –hard HEAD~1′
  6. 合并新的分支到 ruggedisation: ‘git merge my-new-branch’
  7. 检出 master (‘git checkout master’), 合并新分支 (‘git merge my-new-branch’), 然后检查合并后的情况,接着移除合并 (‘git reset –hard HEAD~1′).
  8. 提交新的分支 (‘git push origin my-new-branch’) 并记录 pull 请求

翻译:“奶奶,在高速公路上开车很容易的。松开离合器,让转速超过 6000 转使车轮打滑,然后进入第一个弯道并上高速公路,看路牌到出口前,使用手刹漂移转向出口。

6. 维护简单,但是提交麻烦

Git 很强大的一点就是代码基准库的维护,你必须合并来自大量不同源的提交,非常适合大规模并行开发。但是这些都不是为大多数 Git 的用户设计的,他们只是需要编写代码,可能好几个月都在同一个分支上,对他们来说 Git 是带有 4 个手柄的双锅的咖啡机,但用户只想立即喝到咖啡。

有趣的是,我并不认为这是 Git 在设计中做的权衡。它完全是忽视了真正的用户需求、混淆架构和接口。如果你是一个架构师,那么 Git 是很棒的。但对用户来说它很糟糕,已经有不少人在为 Git 编写一些简化的接口,例如 easygit。

7. 不安全的版本控制

作为一个版本控制系统而言,它必须承诺的就是:一旦代码提交到系统,那么我将保证代码的安全,你做的任何改动你都可以找回。而 Git 食言了,有很多方法可以让整个资料库完全崩溃而且不可恢复:

  1. git add . / … / git push -f origin master
  2. git push origin +master
  3. git rebase -i <some commit that has already been pushed and worked from> / git push

8. 将版本控制库维护者的责任移给贡献者

在传统的开源项目中,只需要一个人负责处理分支和合并这样复杂的操作,那就是维护者。而其他人只需要简单的更新提交、更新提交、不断的更新提交。而现在 Git 让每个用户都需要了解作为维护者才需要知道的各种操作,烦不胜烦。而维护者呢,无所事事,翘起二郎腿喝咖啡。

9. Git 的历史是一堆谎言

开发工作主要的产出就是源代码,一个维护良好的代码历史就对一个产品来说非常的重要,关于重新基准化有很多的争论,多数是依赖于对凌乱合并和不可读的日子的审美判断。而重新基准化为开发者提供一个“干净整洁”的却毫无用途历史记录,而实际上正确的解决方法是更好的日志输出以及对不想要的合并进行过滤。

10. 简单任务也要诸多命令

如果你在开发一个开源项目,你做了一些改变,然后想与其他人分享,你只需要:

  1. 修改代码
  2. 执行 svn commit

如果你增加了一些新文件:

  1. 添加文件
  2. svn add
  3. svn commit

如果你的项目托管在 Github 类的网站中,那么你需要:

  1. Make some changes
  2. git add [not to be confused with svn add]
  3. git commit
  4. git push
  5. 到此为止,你的更改只完成了一半,接下来你需要登录到 Github,查找你的提交,然后发布一个 “pull request” ,这样其他人才可以获取你的改动

在现实中,Github 的维护者希望你的改动是功能方面的分支,他们会要求你这样操作:

  1. git checkout master [to make sure each new feature starts from the baseline]
  2. git checkout -b newfeature
  3. Make some changes
  4. git add [not to be confused with svn add]
  5. git commit
  6. git push
  7. 然后登录到 Github,切换到你的新特性分支,发布 “pull request”

为了将你的更改从你的本地目录中移到实际的项目资源库,你需要:add, commit, push, “click pull request”, pull, merge, push.

下面是一个流程图向你展示一个典型的开发者在 Subversion 上要做的工作:

“Bread and butter” 是与远程 SVN 资料库操作的命令和概念。

然后我们再来看看如果你的项目托管在 Github 上会是怎样的:

如果 Git 的强大之处是分支和合并,那么它的弱点就是让简单的任务变得非常复杂。

本文由 OSCHINA 翻译自:10 things I hate about Git ,转载请注明:

文章出处:我痛恨 Git 的 10 个理由