所以,这是一个有趣的小编程挑战.我正在写一个快速的方法来确定特定年份的所有市场假期,然后我开始阅读有关复活节的信息,并发现了确定其日期的逻辑是多么疯狂 - 春天之后的逾越节满月后的第一个星期日春分!有人知道现有的函数来计算给定年份的复活节日期吗?
当然,这可能并不那么难; 我想我会问,以防有人已经这样做了.(这似乎很有可能.)
更新:实际上,我真的在寻找耶稣受难日(复活节前的星期五)的日期......我只是觉得复活节会让我在那里.既然我在美国,我认为我正在寻找天主教复活节?但如果我错了,也许有人可以纠正我.
*通过"疯狂"我的意思,就像,参与.没有任何令人反感的......
我和一位同事在这个问题上来回走动,我希望得到一些外界意见,看看我提出的解决方案是否是一个好主意.
首先,免责声明:我意识到"优化DateTime.Now
" 的概念对你们中的某些人来说听起来很疯狂.我有几个先发制人的防御措施:
DateTime.Now
很慢(相对来说).下面的方法是更快.现在,问题本身.
基本上,通过测试,我们发现DateTime.Now
运行大约需要25个滴答(大约2.5微秒).当然,这可以在数千到数百万次通话中取平均值.看起来第一个呼叫实际上需要花费大量时间,后续呼叫要快得多.但仍然是25个蜱是平均值.
然而,我和我的同事注意到,DateTime.UtcNow
运行时间要少得多 - 平均只需0.03微秒.
鉴于我们的应用程序永远不会在夏令时发生变化时运行,我的建议是创建以下类:
public static class FastDateTime {
public static TimeSpan LocalUtcOffset { get; private set; }
public static DateTime Now {
get { return DateTime.UtcNow + LocalUtcOffset; }
}
static FastDateTime() {
LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,确定本地时区的UTC偏移一次 - 在启动时 - 从那时起利用速度DateTime.UtcNow …
我正在使用Selenium的WebDriver为我正在进行自我教育的ASP.NET MVC应用程序运行一些SpecFlow测试.
使用FirefoxDriver
,ChromeDriver
等所有需要很长时间来运行,它实际上是非常令人沮丧的使用(在我看来).
我读过一个HtmlUnitDriver
据说比基于浏览器的驱动程序快得多的内容; 但我似乎无法在.NET客户端库中找到一个版本(只有Java).那里有.NET版本吗?
从以前的经验来看,我一直认为在null实例上调用扩展方法是完全合法的(尽管可能不可取).所以在C#中,这段代码编译并运行:
// code in static class
static bool IsNull(this object obj) {
return obj == null;
}
// code elsewhere
object x = null;
bool exists = !x.IsNull();
Run Code Online (Sandbox Code Playgroud)
但是,我只是为我的开发团队的其他成员组建了一小组示例代码(我们刚刚升级到.NET 3.5,我已经被分配了让团队加快一些新功能的任务我们可以使用),我写了我认为是上面代码的VB.NET等价物,但却发现它实际上抛出了一个NullReferenceException
.我写的代码是这样的:
' code in module '
<Extension()> _
Function IsNull(ByVal obj As Object) As Boolean
Return obj Is Nothing
End Function
' code elsewhere '
Dim exampleObject As Object = Nothing
Dim exists As Boolean = Not exampleObject.IsNull()
Run Code Online (Sandbox Code Playgroud)
调试器就在那里停止,好像我调用了一个实例方法.我做错了什么(例如,我在C#和VB.NET之间定义扩展方法的方式有一些细微差别)吗?在VB.NET中调用null实例上的扩展方法实际上是不合法的,尽管它在C#中是合法的吗?(我原以为这是一个.NET的东西,而不是语言特定的东西,但也许我错了.)
任何人都可以向我解释这个吗?
在我公司工作了一段时间,我们使用了一个自行开发的ObjectPool<T>
实现,它提供对其内容的阻止访问.它非常简单:a Queue<T>
,a ,object
锁定,以及在AutoResetEvent
添加项目时向"借用"线程发出信号.
该类的肉真的是这两种方法:
public T Borrow() {
lock (_queueLock) {
if (_queue.Count > 0)
return _queue.Dequeue();
}
_objectAvailableEvent.WaitOne();
return Borrow();
}
public void Return(T obj) {
lock (_queueLock) {
_queue.Enqueue(obj);
}
_objectAvailableEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)
我们一直在使用这个和其他一些集合类而不是那些System.Collections.Concurrent
因为我们使用的是.NET 3.5而不是4.0.但最近我们发现,由于我们使用无扩展,我们实际上做有Concurrent
提供给我们的命名空间(在System.Threading.dll).
当然,我认为既然BlockingCollection<T>
是Concurrent
命名空间中的核心类之一,它可能会提供比我或我的队友写的更好的性能.
所以我尝试编写一个非常简单的新实现:
public T Borrow() {
return _blockingCollection.Take();
}
public void Return(T obj) {
_blockingCollection.Add(obj);
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,根据一些简单的测试(从多个线程借用/返回池几千次),我们的原始实现在性能方面显着优势BlockingCollection<T>
.他们似乎都工作正常 ; 只是我们原来的实现似乎要快得多.
我的问题: …
我完全理解Threading.Interlocked类提供的原子性; 但是,我不明白为什么Add函数只提供两个重载:一个用于Integers,另一个用于Longs.为什么不双打,或任何其他数字类型?
显然,更改Double的预期方法是CompareExchange; 我认为这是因为修改Double比修改Integer更复杂.我还不清楚为什么,如果CompareExchange和Add都能接受整数,他们也不能同时接受双打.
更新:好吧,现在我已经完成了它:我向微软提交了一个关于此的错误报告,因为我严重怀疑这是正确的行为.那就是说,我仍然不能100%肯定对这个问题有什么看法; 所以我可以看到什么是"正确的"是开放的某种程度的解释.
我的感觉是,微软会接受这是一个错误,或者回应一个using
语句中的可变值类型变量的修改构成未定义的行为.
此外,对于它的价值,我至少猜测这里发生了什么.我怀疑编译器正在为闭包生成一个类,将局部变量"提升"到该类的实例字段; 因为它在一个using
街区内,所以它正在建造这个领域readonly
.正如LukeH在对另一个问题的评论中指出的那样,这会阻止方法调用,例如MoveNext
修改字段本身(它们会影响副本).
注意:我已经缩短了这个问题的可读性,尽管它仍然不是很短.有关完整的原始(较长)问题,请参阅编辑历史记录.
我已经阅读了我认为是ECMA-334相关章节的内容,似乎无法找到这个问题的结论性答案.我将首先说明问题,然后为感兴趣的人提供一些附加评论的链接.
如果我有一个可实现的可变值类型IDisposable
,我可以(1)调用一个方法来修改using
语句中局部变量值的状态,并且代码的行为与我期望的一样.但是,一旦我在语句中的闭包内捕获了有问题的变量using
,(2)在本地范围内不再可以看到对值的修改.
只有在闭包内和using
语句中捕获变量的情况下,此行为才会显现; 当只有一个(using
)或其他条件(闭包)存在时,这是不明显的.
为什么在using
语句中的闭包内捕获可变值类型的变量会改变其本地行为?
下面是说明第1项和第2项的代码示例.两个示例都将使用以下演示Mutable
值类型:
struct Mutable : IDisposable
{
int _value;
public int Increment()
{
return _value++;
}
public void Dispose() { }
}
Run Code Online (Sandbox Code Playgroud)
using
块中变换值类型变量using (var x = new …
Run Code Online (Sandbox Code Playgroud) 由于struct
in C#由其成员的位组成,因此您不能拥有T
包含任何T
字段的值类型:
// Struct member 'T.m_field' of type 'T' causes a cycle in the struct layout
struct T { T m_field; }
Run Code Online (Sandbox Code Playgroud)
我的理解是上述类型的实例永远不能被实例化* - 任何尝试这样做会导致实例化/分配的无限循环(我猜这会导致堆栈溢出?**) - 或者,另外,另一个看待它的方式可能是定义本身没有意义; 也许这是一个弄巧成拙的实体,有点像"这句话是假的".
但奇怪的是,如果你运行这段代码:
BindingFlags privateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
// Give me all the private instance fields of the int type.
FieldInfo[] int32Fields = typeof(int).GetFields(privateInstance);
foreach (FieldInfo field in int32Fields)
{
Console.WriteLine("{0} ({1})", field.Name, field.FieldType);
}
Run Code Online (Sandbox Code Playgroud)
...您将获得以下输出:
m_value (System.Int32)
看来我们正在"骗"到这里***.显然,我的理解是原始类型,如int
,double
等必须在C#的肠子深跌一些特殊的方法(你不能在系统方面的系统中定义每一个可能的单位来定义......可以吗? -不同的话题, 而不管!); …
假设我想在jQuery Mobile完成渲染UI后运行一些代码.该mobileinit
事件不会工作,因为它提出了之前发生这种情况.快速谷歌搜索似乎表明,简单使用$(document).ready
将无法与JQM一起使用; 但我只是尝试了它(后面称之为mobileinit
)并且它对我有用:我的代码运行并动态更新元素等等.所以我想知道,是否有一些原因我不应该使用它(它不可靠或混淆JQM),或者那里有关于它的信息根本不准确?我错过了什么?
更新:请参阅此处进行演示.
我们这些在VB/VB.NET中工作的人看到的代码类似于这种令人厌恶的代码:
Dim name As String = IIf(obj Is Nothing, "", obj.Name)
Run Code Online (Sandbox Code Playgroud)
我说"憎恶"有三个简单的原因:
IIf
是一个函数,所有参数都被评估; 因此,如果obj
在上述调用中没有任何内容,那么NullReferenceException
将抛出一个.对于习惯于使用C#等语言的短路三元运算符的人来说,这是出乎意料的行为.IIf
是一个函数,所以它会产生函数调用的开销.同样,虽然这不是什么大问题,但对于那些期望它表现为语言固有的三元操作的人来说,这感觉不对.IIf
是非泛型的,因此接受类型的参数Object
,这意味着以下调用框(我相信)总共有三个整数:
' boxes 2nd and 3rd arguments as well as return value '
Dim value As Integer = IIf(condition, 1, -1)
现在,在一些更新版本的VB.NET中(我不确定数字是多少),If
引入了运算符,其IIf
功能与函数完全相同,但(据我所知)没有相同的缺点.也就是说,它确实提供了短路,并且它是一种内在的VB操作.但是,我不确定最后一部分.在MSDN文档似乎并没有表示是否If
箱及其参数与否.有人知道吗?
.net ×7
c# ×3
vb.net ×3
datetime ×2
struct ×2
atomic ×1
blocking ×1
boxing ×1
calendar ×1
closures ×1
collections ×1
computus ×1
ienumerator ×1
jquery ×1
mutable ×1
objectpool ×1
optimization ×1
performance ×1
primitive ×1
selenium ×1
value-type ×1
webdriver ×1