设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 8999|回复: 24
打印 上一主题 下一主题

[已经解决] if not和unless有什么区别

[复制链接]

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
1
发表于 2010-7-5 00:00:34 | 显示全部楼层
其实这属于架构不独立的细节问题,我刚用你的代码在 Linux AMD Opteron 2CPU/8GB/Sun Fire X4200 上测试,结果是:

  1. Rehearsal --------------------------------------------------
  2. if not           3.520000   0.580000   4.100000 (  4.102890)
  3. unless           3.160000   0.500000   3.660000 (  3.667306)
  4. ----------------------------------------- total: 7.760000sec
  5.                      user     system      total        real
  6. if not           3.150000   0.500000   3.650000 (  3.649854)
  7. unless           3.140000   0.700000   3.840000 (  3.843158)
复制代码
运行时环境稳定下来后似乎也不见得有啥区别
然后试了下 Solaris 4CPU/8GB/Sun V440
  1. Rehearsal --------------------------------------------------
  2. if not          22.170000  34.620000  56.790000 ( 56.824471)
  3. unless          23.200000  34.020000  57.220000 ( 57.239640)
  4. --------------------------------------- total: 114.010000sec

  5.                      user     system      total        real
  6. if not          21.620000  35.040000  56.660000 ( 56.664212)
  7. unless          22.950000  33.930000  56.880000 ( 56.911735)
复制代码
也没看出明显区别

从形式语言的翻译规则上来看,前者是应该先取反,然后分歧跳转,而后者直接分歧跳转。但实际上解释器也会做相应的优化,比如 if not expr 这种语法,解释器完全可以翻译成:

        cmp eax 0                    ; 假设这里 eax 是 expr 解析后的结果值
        je if_not
         ; ..... if not not false
if_not:
        ; ...... if not false

而不是:
        not eax
        cmp eax 1
        je if_not
         ; ..... if not not false
if_not:
        ; ...... if not false

当然上面的指令只是针对 x86,不同的架构也可能有不同的表现

点评

也就是不必过分纠结if not和unless熟快熟慢了?  发表于 2010-7-5 00:25

评分

参与人数 1星屑 +300 收起 理由
DeathKing + 300 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
2
发表于 2010-7-5 00:52:41 | 显示全部楼层
具体看解释器是如何实现的,这个我无从得知,但从汇编方面分析,差别基本上可以无视,就像当年某高手煞有介事的强调 i++ 和 ++i 的区别一样

点评

moy
那个确实有区别...至少在C语言里操作不当读出来的值会不一样...  发表于 2010-7-5 01:24
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
3
发表于 2010-7-5 01:12:24 | 显示全部楼层
回复 DeathKing 的帖子

呵呵,对的,不过我说的是效率,i++ 要额外使用一个寄存器保存 i 的值作为返回值,然后再把 i 加 1,而 ++i 直接把 i 加 1,返回 i
这个区别在硬件飞速发展的今天已经是微乎其微了,虽然很多高手还是坚持“效率完美主义”,但我觉得应该把精力放在分析算法复杂度上,那才是大头儿
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
4
发表于 2010-7-5 01:20:51 | 显示全部楼层
回复

本来想点评的,结果回复了自己一个空帖子,防止被版主抓到而已灌水,将点评放到这里了。。。

从人 ...
darkdrium 发表于 2010-7-5 00:58


哦,理解错了,但至少英语语法里不需要那个“否则”的:
unless it rains tomorrow, we would go out.
可能用在句末更顺口,Ruby 也支持这样的语法:
goOut() unless rain

点评

是啊,其实还是语言的问题,unless在汉语中并不常用,因为等价于“除非”+“否则”  发表于 2010-7-5 01:23
优美、简洁的修饰符结构?  发表于 2010-7-5 01:21
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
5
发表于 2010-7-5 01:33:24 | 显示全部楼层
本帖最后由 紫苏 于 2010-7-5 06:19 编辑

解释性语言运行程序的效率确实没有直接执行编译好的机器码高,但她的一大特点就是调试周期比编译性语言的周期短(这个周期的过程,前者是:编辑代码 - 解释 - 调试;后者是:编辑代码 - 编译链接 - 运行 - 调试)。解释性语言只需要整体分析一下语法,然后就马上开始执行第一条语句,而编译性语言在语法分析的同时还需要把所有代码编译为机器可读的二进制码,然后把不同的对象文件链接起来。这在制造原型和测试的时候就比较重要了,你调试的次数越多,就越能通过使用解释性语言来节省时间。编译性语言虽然也有一些优化速度的机制,如预编译文件,但整体还是不如解释性语言

恩,matz的确是这样想的,所以就抛弃了指针?

DeathKing 发表于 2010-7-5 01:14


其实不要指针的原因是多方面的,其中一个比较重要的是为了在内存托管机制下减少堆内存碎片——在大多数现代高级语言中,只要是有垃圾回收机制的,都不会提供指针。在堆中分配的内存通常都是零散的(这也是为什么这种内存区域叫“堆”,顾名思义,没有次序的一堆),会导致堆内存中产生很多碎片,而当对象被垃圾回收后,GC 就会紧缩内存,整理碎片,这样才能提高分配堆内存的效率(因为分配堆内存需要在“杂乱的一堆”中找到一块足够大的连续空间)。这样一来,就需要把内存中的对象移来移去,自然指向这个对象的引用的地址也会改变。由于所有该对象的引用在底层都是指向同一个指针(而这个对象唯一的指针又指向该对象),所以只需要改变这个指针的值,就能改变所有引用指向的值。但这在 C++ 中却是不可能的,因为 C++ 可以操纵任意数量的指针指向任意地址
除此之外还有其它原因,比如安全性:有指针就有可能导致内存泄漏,崩溃,访问不可访问、释放已被释放的地址而导致段错误等,引用则不会出现这些问题
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-7 13:58

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表