发表评论
首先,我也比较相信位运算的效率比取模更高,但楼主既然提出了这种方式比模运算更高效的观点,为什么不提供性能测试数据来支持你的观点呢?这就不够严谨了。
另外,
if ((a & s) == 0)
{
return true;
}
else
{
return false;
}
为什么不可以写成
return ((a & s) ==0);
呢?这样虽然从性能的角度来看变化不大,但至少可以让程序看上去更简洁精炼,毕竟这种简洁并不会损失可读性呀。
学习了,一句话
return ((a & s) ==0);
#6楼 [
楼主]2007-11-21 14:42 |
@ZeroCool
确实,return ((a & s) ==0); 更好。
非常同意您的观点,谢谢。
#7楼 [
楼主]2007-11-21 14:49 |
@1-2-3
找不到工作。
用扩展方法更好,不需要 OddEven 这个类。
using System;
namespace IsEven
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(3.IsEven());
Console.ReadLine();
}
}
public static class IntExtensions
{
public static bool IsEven(this int i)
{
return (i & 1) == 0;
}
}
}
@木野狐(Neil Chen)
不错更简洁,用了新特性,
不过也得他的vs支持哦
#12楼 [
楼主]2007-11-21 15:04 |
@木野狐(Neil Chen)
请问这个是.net3.0里面新加的机制吗?以前没有接触过。
http://blog.joycode.com/scottgu/archive/2007/10/10/109268.aspx
return ((a & s) == 0);
受益了:D
将对2的n次访求模自动转换为按位与,这是编译器优化任务之一。
这帖子真冷
如果都写成了return ((a & s) ==0);了
那么写成return ((a & 1) ==0);有能怎样
再说,有必要为了判断奇数偶数而去构建一个类么?
我一直认为高级编程中,内存才是最宝贵资源
呵呵,传统技巧。
以位运算代替乘除法的场合还有很多,比如计算2倍,4倍,1/4,1/8什么的。
用异或省去临时变量替换两个变量的方法堪称位此类应用中的经典
但用的时候要注意有符号数和无符号数的区别、数值类型位长、溢出安全问题等等。
@Cat Chen
:-) 我也这么认为。但不知道编译器是否真这么做了。
个人感觉这种苛求是没有什么必要的,请问你这么写代码是否容易理解了呢?
即使是模2算法与位以德算法在实际的使用中(只要不是频繁的调用)也不会见到任何的性能损失的.
我还有一个办法就是 使用右移,然后判断zf
究竟是位与运算快还是右移运算快?
确实这种写法没见过得学习学习
public static class IntExtensions
{
public static bool IsEven(this int i)
{
return (i & 1) == 0;
}
}
这个效率方面的说法还要经过实际的测试啊。
个人感觉取模操作效率也不会差。
调用一下Static Method,代价可能都是任何奇偶判断方法的百倍
只学习了一条话:return (i & 1) == 0;
同时问一句:
public static bool IsEven(this int i)
和
static public bool IsEven(this int i)
有什么区别?
#32楼 [
楼主]2007-11-22 11:59 |
@wenanry
没有区别!
#34楼 [
楼主]2007-11-22 13:46 |
可以用以下代码进行效率的测试:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication44
{
class Program
{
static void Main(string[] args)
{
int a = -25547788;
int len = 500000000;
DateTime start1 = DateTime.Now;
for (int i = 0; i < len; i++)
{
OddEven.IsEven(a);
}
TimeSpan ts1 = DateTime.Now - start1;
Console.WriteLine("使用位操作的时间:" + ts1.TotalMilliseconds);
DateTime start2 = DateTime.Now;
for (int i = 0; i < len; i++)
{
Mod2.IsEven(a);
}
TimeSpan ts2 = DateTime.Now - start2;
Console.WriteLine("使用求模操作的时间:" + ts2.TotalMilliseconds);
}
}
/// <summary>
/// 判断一个整数是奇数还是偶数。使用位操作
/// </summary>
static class OddEven
{
static public bool IsEven(int a)
{
return ((a & 1) == 0);
}
static public bool IsOdd(int a)
{
return !IsEven(a);
}
}
/// <summary>
/// 判断一个整数是奇数还是偶数。使用求模操作
/// </summary>
static class Mod2
{
static public bool IsEven(int a)
{
return ((a % 2) == 0);
}
static public bool IsOdd(int a)
{
return !IsEven(a);
}
}
}
实测差距不大,相较位运算法,与2求模法存在一个2%~4%的额外损耗。测试使用随机数生成器生成一亿个正整数进行测试。
DateTime startTime = DateTime.Now;
for (int i = 0; i < size; i++)
{
if ((r.Next() & 1) == 0)
oddCount++;
else
evenCount++;
}
DateTime endTime = DateTime.Now;
#36楼 [
楼主]2007-11-22 14:10 |
@560889223
>与2求模法存在一个2%~4%的额外损耗
这是怎么获得的数据啊?
为什么IsOdd还要去调用一次IsEven呢,函数体本来就很简洁的,多一次函数调用很高效么
还是用简洁、易懂的方式比较好,毕竟现在电脑CPU速度已经很过剩了~~剩下的就是对人大脑的考验了:)
呵呵,一眼就看出来你是个学生
跟我当年一个样
为了点儿小性能废了半天劲,最后人家还不知情
这种研究很有益,但如果是实际开发要在程序性能和开发进度间仔细权衡
#42楼 [
楼主]2008-03-04 09:39 |
@floodpeak
是,谢谢指教。
@floodpeak
我看你连个学生也不如。你做事完全只是为了让别人知情么?
象你这样的态度,进度也高不到哪里去。虽然快快交差了,但是毛病一堆。算上你调试、优化的时间,比人家还多出一截来。
讲究细节的目的不仅仅是为了手头的某个程序,而是为了养成一些良好的习惯,有了这些习惯,提升系统质量无需任何成本。