我很困惑.在CodeRage今天,Marco Cantu说CharInSet很慢,我应该尝试使用Case语句.我在我的解析器中这样做,然后用AQTime检查加速是什么.我发现Case语句要慢得多.
执行的4,894,539次:
而不是CharInSet(P ^,['',#10,#13,#0])做inc(P);
时间为0.25秒.
但执行次数相同:
而确实是 ',#10,#13,#0的
案例P ^
:break;
else inc(P);
结束;
"while True"需要0.16秒,第一种情况需要0.80秒,else情况需要0.13秒,总计1.09秒,或者超过4倍.
CharInSet语句的汇编代码是:
添加edi,$ 02
mov edx,$ 0064b290
movzx eax,[edi]
调用CharInSet
测试a1,a1
jz $ 00649f18(返回add语句)
而案例逻辑就是这样:
movzx eax,[edi]
sub ax,$ 01
jb $ 00649ef0
sub ax,$ 09
jz $ 00649ef0
sub ax,$ 03
jz $ 00649ef0
add edi,$ 02
jmp $ 00649ed6(返回movzx声明)
案例逻辑在我看来是使用非常有效的汇编程序,而CharInSet语句实际上必须调用CharInSet函数,该函数在SysUtils中并且也很简单,是:
function CharInSet(C:AnsiChar; const CharSet:TSysCharSet):Boolean;
begin
结果:= CharSet中的C;
结束;
我认为这样做的唯一原因是因为在Delphi 2009中不再允许['',#10,#13,#0]中的P ^,因此调用会转换类型以允许它.
尽管如此,我对此感到非常惊讶,仍然不相信我的结果.
AQTime是否测量错误,我在这个比较中遗漏了什么,或者CharInSet真的是一个值得使用的有效函数吗?
结论:
我想你明白了,巴里.感谢您抽出宝贵时间做详细示例.我在我的机器上测试了你的代码,得到了.171,.066和.052秒(我猜我的桌面比你的笔记本快一点).
在AQTime中测试该代码,它给出:三次测试的0.79,1.57和1.46秒.在那里,您可以看到仪器的大量开销.但令我惊讶的是,这种开销将明显的"最佳"结果改为CharInSet函数,这实际上是最差的.
所以Marcu是正确的,CharInSet更慢.但是你无意中(或者可能是故意的)通过在Set方法中提取CharInSet用AnsiChar(P ^)做的事情给了我一个更好的方法.除了比case方法更小的速度优势,它也比使用案例更少的代码和更容易理解.
您还让我意识到使用AQTime(以及其他仪器分析器)进行错误优化的可能性.知道这一点将有助于我决定使用Delphi的Profiler和内存分析工具,这也是我的问题的另一个答案AQTime如何做到这一点? …
我已经注意到O(1)在讨论涉及散列和搜索类型的算法时的一些非常奇怪的用法,通常是在使用语言系统提供的字典类型的上下文中,或者使用使用数组使用的字典或散列数组类型 - 索引符号.
基本上,O(1)意味着以恒定时间和(通常)固定空间为界.一些非常基本的操作是O(1),尽管使用中间语言和特殊虚拟机往往会扭曲思考的人(例如,如何将垃圾收集器和其他动态过程分摊到O(1)活动之外).
但是忽略了延迟,垃圾收集等的摊销,我仍然不明白如何假设某些涉及某种搜索的技术可以是O(1),除非在非常特殊的条件下.
虽然我之前已经注意到这一点,但是在Pandincus问题中出现了一个例子,"'正确'集合用于在C#.NET中获取O(1)时间内的项目?" .
正如我在那里所说的那样,我所知道的唯一一个提供O(1)访问作为保证边界的集合是一个带有整数索引值的固定绑定数组.假设通过一些映射到随机存取存储器来实现该阵列,该存储器使用O(1)操作来定位具有该索引的单元.
对于涉及某种搜索以确定不同类型索引(或具有整数索引的稀疏数组)的匹配单元的位置的集合,生活并不那么容易.特别是,如果存在可能的碰撞和拥堵,则访问不完全是O(1).而如果集合是灵活的,必须认识和摊销扩大基础结构的成本(如树或哈希表),其纾缓交通挤塞(例如,高发病碰撞或树的不平衡).
我永远不会想到将这些灵活和动态的结构称为O(1).然而,我认为它们作为O(1)解决方案提供,而没有任何必须保持的条件,以确保实际上具有O(1)访问(以及使该常数可忽略地小).
问题:所有这些准备都是一个问题.O(1)的偶然性是什么?为什么这么盲目地被接受?是否认识到即使O(1)可能不合需要地大,即使接近常数?或者O(1)只是将计算复杂性概念挪用于非正式用途?我很困惑.
更新:答案和评论指出了我自己定义O(1)的习惯,我已经修复了.我仍然在寻找好的答案,在一些情况下,一些评论主题比他们的答案更有趣.
我安装了Visual Studio 2008 SP1,当我在Moq Framework中使用lambda表达式时它崩溃了.
起初我认为问题是Resharper ...但是现在我已经卸载它,VS 2008仍然崩溃.我每次都能复制这个问题.
我想也许它可能是其他一些导致问题的插件而不是VS 2008 ...但我不能确定.
那么我想要找到的是Visual Studio记录发生的崩溃的地方?
不幸的是我无法找到它...有没有人知道它是否存在,如果存在,在哪里看?
提前致谢!
有关如何检查该列表是否是另一个列表的任何想法?
具体来说,我有
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
Run Code Online (Sandbox Code Playgroud)
如何使用LINQ检查t2是否为t1的子集?
默认情况下,IIS6不提供.json(没有通配符MIME类型).
因此,抛出了未找到的404.然后我添加一个新的MIME类型(.json, text/plain or application/x-javascript or application/json),它工作正常.
但是,当您添加新映射(Home Directory -> Configuration -> Add) with .json, C:\WINDOWS\system32\inetsrv\asp.dll" GET,POST"并尝试浏览到该文件时,您将获得404.
如果您删除映射并尝试POST or GET使用它,则会得到一个405.
...
建议?
在Windows上我可以做CreateProcess(..., CREATE_NEW_CONSOLE, ...),我的子进程(控制台应用程序,而不是GUI)将在新窗口中启动.在Mac OS上模拟此操作的最简单方法是什么?
我将以示例的形式对此进行说明,以使其更加清晰.
说我有一个动物矢量,我想通过阵列,看看元素是狗还是猫?
class Dog: public Animal{/*...*/};
class Cat: public Animal{/*...*/};
int main()
{
vector<Animal*> stuff;
//cramming the dogs and cats in...
for(/*all elements in stuff*/)
//Something to the effect of: if(stuff[i].getClass()==Dog) {/*do something*/}
}
Run Code Online (Sandbox Code Playgroud)
我希望有点清楚.我知道关于typeid,但是我没有任何Dog对象来比较它,如果可以的话我想避免创建一个Dog对象.
有没有办法做到这一点?提前致谢.
我正在寻找包含与Matlab的金融和金融衍生工具箱类似功能的东西,但没有现金花在matlab上.我将不胜感激任何有关免费或开源图书馆或程序的信息,这些信息可让我轻松计算利率,风险等.
你能告诉我如何在C++程序中使用线程,我怎样才能编译它,因为它将是多线程的?你能告诉我一些可以从root开始的好站点吗?
谢谢