re: 从C# 3.0到F# Angel Lucifer 2008-07-25 23:37
说实话,俺不看好 F# 的前途。它虽然跟 C# 一样是 CLR 一等公民,但考虑到由于 C-like 语言的遗留资源,实在是怀疑此语言能够大规模普及。
re: 再谈 BigInteger - 使用快速傅里叶变换 Angel Lucifer 2008-07-25 23:26
楼主深入钻研的精神值得称赞!
顶你个肺!
哈哈。
re: 使用快速傅里叶变换计算大整数乘法 Angel Lucifer 2008-07-24 11:15
佩服下楼主的数值计算知识,这正是俺欠缺的方面之一。
那些数学公式几乎都忘干净了,就剩下加减乘除了,哈哈。
如果只是 C-Style 的字符串,.NET 的 String 类可以自行处理。
但俺以为这实际上是个败笔,Developer 不应该挣扎于这种毫无意义的字符串转换中。它的存在纯粹为了兼容。
PS: STL String 更加啰嗦麻烦。
re: 惊醒:开平事件 Angel Lucifer 2008-07-23 12:32
这是怎么回事?
俺先Google之。
re: Windows Process内存组织结构及重要域解析 Angel Lucifer 2008-07-22 16:51
沙发,学习,:-)
re: WPF程序单例实现 Angel Lucifer 2008-07-22 13:07
而且俺质疑楼主所提方法的高效性和安全性。
re: WPF程序单例实现 Angel Lucifer 2008-07-22 13:03
同意楼上的,使用 Mutex 锁就可以了。
这个问题,我认为对于实现 MemoryModel 的开发人员来说要重视。
对于应用开发人员来说问题不大,呵呵。
volatile 压根不能作为同步手段来使用。
不过还是要对楼主如此深入钻研此问题的精神赞一个,:-)
re: 交朋友的学问 Angel Lucifer 2008-07-20 19:23
君子之交淡如水。
再次插入前10,这次比上次前进一位,哈哈。
re: 周末话题-语法糖 Angel Lucifer 2008-07-20 17:46
过多的语法糖,只会无谓提高语言的门槛。
简单才是美。
re: 周末话题-语法糖 Angel Lucifer 2008-07-20 17:42
过犹不及。不是所有东西都可以塞在语法层面,看看 C++ 。
C++ 0x 引入的 Concept 估计会有很多人抵制的。
这种非侵入式的接口,需要大多数人改变思维方式,重新培训,也不见得是一种好事。
re: 应用程序域(Application Domain) Angel Lucifer 2008-07-20 17:35
进程间通信有多种技术,呵呵。
管道,文件映射,油槽,Socket都是这种技术。
.NET的Remoting的设计目标远大于此。
re: Priority Queue(Heap)的实现及其应用 Angel Lucifer 2008-07-19 14:27
这是二叉堆实现的优先级队列,它有个缺陷就是合并队列麻烦,而且时间复杂度也蛮高的。
如果有合并需求,可以考虑使用偶堆来实现优先级队列,这是个很有竞争力的数据结构,呵呵。
俺有个 .NET 版的文章:
http://www.cnblogs.com/lucifer1982/archive/2008/06/13/1218559.html
PS: 老兄的 Blog 在 Firefox 3.0 下打开好卡,CPU 占用 100%。而且老是重新连接 www.8box.cn
使用 yield 最好在实现 IEnumerator<T> 接口时使用。
楼主有没有考虑分析一下 yield break ?
re: 工作一年总结 Angel Lucifer 2008-07-19 13:31
嗯,拜下未来的大师。
re: 并行思维 [I] Angel Lucifer 2008-07-19 13:26
@Jeffrey Zhao
@lbq1221119
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-19 13:16
忘记你是双核的了,呵呵。
ThreadPool.SetMaxThreads 不能设置最大线程数小于计算机的处理器数目。因为设置不成功,所以还是默认的每CPU 250。
双核情况下,可以考虑设置成 2 或者以上,只要它能返回 true 。
代码可以考虑使用你自己的嵌套三层或者 N 层。
PS : 在实际的异步编程中,可能会大量使用 ThreadPool.QueueUserWorkItem 或者异步委托(它基于线程池实现)。如果不注意,很快就会超过 25 导致死锁。我们很难避免这种情况不发生。这正是线程池中线程数量从 25 提升到 250 的原因。
再次PS: 锁机制相当麻烦,一不小心,就会翻船。.NET ThreadPool 的实现也不是十分高效。
re: 并行思维 [I] Angel Lucifer 2008-07-19 12:36
沙发自己做,哈哈。
这实际上还是内存语义取舍的问题,呵呵。
对于 volatile 来说,适用场景有限,而且也不推荐使用这玩意。
详情可以参考:
http://www.cnblogs.com/lucifer1982/archive/2008/03/23/1116981.html
如果开发人员适用 .NET 提供的其他同步机制,则完全不用考虑该问题,因为这些机制都是基于 FullFence 的。
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-19 10:35
本来写了一些解释,结果 Firefox 下老出问题,搞的俺灰心了。
琢磨一下吧,:-)
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-19 10:32
using System.Threading;
namespace Lucifer.CSharp.Sample


{
class Program

{
public static void Main()

{
ThreadPool.SetMaxThreads(1, 1);


WaitCallback callback = delegate
{ MethodA(); };
callback.BeginInvoke(null, null, null);

Console.ReadLine();
}

private static void MethodA()

{
Console.WriteLine("Thread A is beginning
");


WaitCallback callback = delegate
{ MethodB(); };
IAsyncResult result = callback.BeginInvoke(null, null, null);

//模拟实际工作。
Console.WriteLine("1
");
Console.WriteLine("2
");
Console.WriteLine("3
");

//这里永远也不会返回。
callback.EndInvoke(result);
}

private static void MethodB()

{
//永远也不会运行到这里,因为线程池线程耗尽,导致资源竞争引发了死锁。
Console.WriteLine("Thread B is beginning
");
}
}
}
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-19 10:09
@银河使者
文字描述太麻烦,用一段代码来说明吧。
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-18 22:28
避免死锁主要还是开发人员的责任,因为线程池并不知道开发人员如何同步。
此外,如果使用 Lock-Free ,则根本不会有死锁的可能。
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-18 22:26
@银河使者
我当然清楚死锁的概念。.NET 3.5 之所以从 25 提高到 250的目的是为了降低发生死锁的概率,而不是说它一定会发生死锁,呵呵。
re: 做了一个简单的DLINQ性能测试 Angel Lucifer 2008-07-18 22:17
结论呢?
re: 走进Linq-Linq大观园 Angel Lucifer 2008-07-18 20:41
老实说,俺还没有看到LINQ的实际意义所在。
或许对那些需要快速开发,而项目组中又缺乏数据库专家的项目颇有些意义吧。
还请楼主指点迷津。
PS: LINQ to Object 比较好玩,:-)
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-18 20:33
仅部分同意,这个问题有相关的说明,线程数并非越多越好,呵呵。
当线程池有太多线程等待其他任务结束时就会出现死锁:一旦所有25个线程都被阻塞的时候,等待中的任务就无法分配到线程了。250只是降低了这种死锁的可能。
re: C#线程系列讲座(3):线程池和文件下载服务器 Angel Lucifer 2008-07-18 20:09
/*
* 在默认情况下,ThreadPool最大可建立500个工作线程和1000个I/O线程
*/
在 .NET 2.0 中, ThreadPool 中默认最大工作线程是每 CPU 25个。
在 .NET 3.5 中, ThreadPool 中默认最大工作线程是每 CPU 250个。
这个变化是为了处理线程池中的死锁,但无法彻底排除死锁的可能性,只是让该问题的发生概率大大减小而已。
由此,可以推知楼主的机器是双核 CPU,安装了 .NET Framework 3.5 或者 .NET Framework 2.0 SP1,:-)。
re: 项目经理的个人修养 Angel Lucifer 2008-07-18 19:54
符合国情的项目经理,呵呵。
re: 不需要强类型, 需要强测试? Angel Lucifer 2008-07-18 19:44
俺认为像Joel此类人或许太关注他所在的软工领域了,而忽视了其他方面。
同意文中观点,检查和测试不一样,检查顶多也就是测试的冰山一角。
抛开 C# 的静态类型检查,因为它那运行时类型检测和可怜的类型推导(这还只是C# 3.0才有的功能),来谈下相对更厉害的C++。
要想做到编译时测试,非常困难。静态编译型语言编译之后会完全丢失其类型信息,当然像 C# 这样的有VM的除外。编译器只能在词法分析阶段检测到类型,如果无类型,它该如何示警?如果无法检测,开发人员的痛苦要加倍了,呵呵。
C++的模板元编程倒有点编译时测试的味道。但是如果没有强类型,那么类型推导会十分困难,如果没有没有类型推导,几乎就没有什么大用处。
更重要的是,逻辑上的错误在编译时该如何测试?更何况,即使测试也不能完全消灭Bug。
此外,强类型带来的好处还有性能上的巨大提升。俺在使用D做模板元编程时,真是深有体会。
俺认为,有所取舍比追求完美更划算。追求完美的代价太高,所以任何软工都是各方取舍的结果。要是听信 Joel 胡侃,会着魔嘀。哈哈。
PS:怪怪兄的文章很有意思。但俺每次都没耐心仔细阅读,有时候思维跳跃的厉害,导致俺这个笨人思维连贯不起来。而且力求逻辑完美,这就好像代码中太多的条件判断淹没了核心算法,让阅读代码的人吃力。
re: .NET调试实例-实验1:死锁 - 回顾 (原创翻译) Angel Lucifer 2008-07-18 15:15
嗯,我是来拜会 Debug 的达人嘀...
re: 探究加密算法 Angel Lucifer 2008-07-16 22:46
re: 关于DllImportAttribute 类型 Angel Lucifer 2008-07-16 05:50
补充下楼主的文章,:-)
Interop 只有在必要的时候才需要使用,比如你要用到的 Native API 没有被 CLR 封装的时候。
Interop 的主要缺点在于它的性能损失和可能会带来 Native 开发的缺陷。
因为 CLR 使用 C++ 封装 Native API,其 InternalCall 的开销比我们自行 Interop 要小,安全性上也有较好的保证。
re: 《博客园精华集》最新进展情况 Angel Lucifer 2008-07-15 15:27
支持一把。
re: 地球:超级生命 Angel Lucifer 2008-07-15 15:20
在俺有生之年是看不到了,只能指望后辈们烧黄纸的时候通知一声了。
貌似那个时候,还有没有烧黄纸的传统,意识是否被控制都难说。
re: WPF不规则窗体图文指南 Angel Lucifer 2008-07-14 01:13
Very Cool.
@吳宇澤
感谢解答。
您的观点是正确的。
因为在 I/O Operations 中 Close 和 Dispose 的确一样,所以俺想当然了。抱歉。
看来使用ADO.NET 中的 Close 和 Dispose ,还是要分场景。
但仍有一处疑惑,设定时间 (默认为 60 秒)有什么依据吗?
俺查阅的资料默认值是 4~8分钟内的一个随机值。
此外,Dispose 虽然会使得 Connection Pool 失效(Source为 this._poolGroup = null;
),但 GC 应该不会立刻强制进行资源回收操作。是否回收,视 GC 认为有无必要来决定。
恳请再次指正。
Close 方法等效于 Dispose 方法,它只是 Dispose 方法的别名而已,都是调用内部的 Dispose(true)。
再次讨论:
BeginInvoke 方法实际上是调用 ThreadPool 中的线程完成操作。
在进行 I/O 操作的时候,虽然看起来跟异步 I/O 的行为很相似,但跟操作系统提供的异步 I/O 还是有区别的。
在 I/O 操作并不频繁密集的时候,BeginInvoke 的 I/O 操作可能比操作系统的异步 I/O 要高效,但一旦密集起来,性能可能会严重下降。
希望楼主能在后续文章内加以区分,:-)
@MarkLEEE
老兄的这种方法远不如楼主提及的高效,不过可以远程访问。
序列化的目标在于保存对象当时的状态。
Clone可不一定。
三,四的方式实际上还是阻塞的。
在主线程内调用 EndXXX 方法,效果跟调用 Thread.Join 方法一样。
因为楼主计算的结果非常快速,所以结果会立刻返回。
虽然基础,不过仍然欢迎楼主写此类文章,:-)
从楼主给出的文章结果看,貌似采用 IL Emit 方式,性能要高些?
re: 开发之路还能走多远 Angel Lucifer 2008-07-11 20:46
俺的看法。
如果基础够扎实,什么新技术都会一点既透。
此外,还有相当重要的一点就是独立思考。
古人说的好,尽信书不如无书。有时候,作者的观点不一定准确,需要自己来甄别。
re: 浅谈 Math.BigMul 方法 Angel Lucifer 2008-07-11 07:12
/*
* 这样看来,在 C# 语言中,方法调用的时间几乎可以忽略不计。
*/
像这种方法体很简短的 Method ,编译器会 inline 的。如果不内联,函数调用在一定的数量级上,开销还是很大嘀。
若不是楼主提及,还真不知道 Math.BigMul 方法的存在,呵呵。
俺倾向于这种结论:Math.BigMul 方法是为了防止程序员在做乘法时忘记了把 int 类型转换为 long 类型。
但这个实在是没有多大的讨论意义,:-(
貌似有个快速选择算法,时间复杂度是O(NlogN)
re: winform中柱状图 Angel Lucifer 2008-07-07 10:22
这...
re: 昨天到今天也很高兴 Angel Lucifer 2008-07-07 09:14
插入前10。
潘老大的功底毋庸置疑,绝对在WINDOWS上浸淫了很多年。
孟老大的文章有时候俺感觉有很强的商业味道,可能是俺小人之心了,呵呵。
要关注学习的技术太多,都没有精力看人文,哲学方面的书籍了。
@金色海洋(jyk)
像老兄这种库性质的东西,尽情的抛异常就可以了。
异常由业务逻辑层,使用库的客户来处理。
@非空
很简单,编译器没有办法知道该处是否有异常抛出,所以无法优化成不带 try 的生成代码。
@Aldebaran's Home
性能监视器。
为了性能调优。
谈下俺的看法。
添加 try...catch 块确实会增加额外的开销,这本身就是由 SEH 决定的。
但是在没有异常抛出的时候,这个额外开销并不大。怕的是 try...catch 块嵌套,尤其是无意识的嵌套。这种累积性的额外开销可能会增长到影响程序性能的地步。此外,不能被编译器优化的是 try...catch 块,而不是其内部编码。
另外就是频繁的抛出异常是性能杀手,因为一旦抛出异常,在辗转展开堆栈,查找异常位置的时候,非常耗费时间。
既然说到这了,顺便再说下关于异常与性能的话题。《.NET 设计规范》里有提及,MSDN 也有那篇文章的内容。它提出了两个模式 Tester-Doer 和 Try-Parse 。
对于库开发人员来说,根本不用在乎上述问题,有问题就抛异常。当然有时候还要考虑下 Try-Parse 模式。真正麻烦的是客户应用开发人员,也就是使用库的开发人员。
还有就是绝大部分异常在产品测试的时候都会得到妥善处理。
Over...