在我的程序中,我处理了数百万个具有特殊字符的字符串,例如"|" 分隔每个字符串中的标记.我有一个返回第n个令牌的函数,就是这样:
function GetTok(const Line: string; const Delim: string; const TokenNum: Byte): string;
{ LK Feb 12, 2007 - This function has been optimized as best as possible }
var
I, P, P2: integer;
begin
P2 := Pos(Delim, Line);
if TokenNum = 1 then begin
if P2 = 0 then
Result := Line
else
Result := copy(Line, 1, P2-1);
end
else begin
P := 0; { To prevent warnings }
for I := 2 to TokenNum do begin
P := …Run Code Online (Sandbox Code Playgroud) 在使用Delphi 2009调试我的应用程序时,我有时会发生以下异常:
这是什么?http://www.beholdgenealogy.com/img/ideexception.gif
这只是偶尔发生,但在按下OK之后,我的IDE和程序都可能会冻结.如果我很幸运,我有时可以在Delphi中进行File/SaveAll,但有时候我不能.无论哪种方式我都被卡住,然后我唯一能做的就是使用Windows任务管理器来关闭Delphi.当然,如果我无法SaveAll,那么我将丢失自上次保存以来所做的所有编辑.
我安装了所有Delphi 2009更新,包括Update 4.我还安装了IDE Fix Pack 2009 2.9.
EurekaLog为我捕获了错误,错误报告给出了以下调用堆栈:
Call Stack Information:
-----------------------------------------------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure/Method |Line |
-----------------------------------------------------------------------------------------------------------
|Running Thread: ID=5068; Priority=0; Class=; [Main] |
|---------------------------------------------------------------------------------------------------------|
|205669C6|dbkdebugide120.bpl |Debug.pas |TDebugger |DBKWndProc |11598[6] |
|777DE49A|ntdll.dll | | |KiUserExceptionDispatcher | |
|7705E0CB|kernel32.dll | | |RaiseException | |
|03E8E3E8|dcc120.dll |WRITEOBJ.OBJ | |C62_0 | |
|03E3066D|dcc120.dll |SYMTAB.OBJ | |MakeOverloadedPropertyList| |
|03E3064C|dcc120.dll |SYMTAB.OBJ | |MakeOverloadedPropertyList| |
|03E30D76|dcc120.dll |SYMTAB.OBJ | |EnterMethod | |
|03E30D6C|dcc120.dll |SYMTAB.OBJ | |FindBaseClassMethod | |
|03DE8D30|dcc120.dll |DECL.OBJ …Run Code Online (Sandbox Code Playgroud) 如何使用TEnumerator按键排序顺序浏览我的TDictionary?
我有这样的事情:
var
Dic: TDictionary<string, string>;
Enum: TPair<string, string>;
begin
Dic := TDictionary<string, string>.create;
Dic.Add('Tired', 'I have been working on this too long');
Dic.Add('Early', 'It is too early in the morning to be working on this');
Dic.Add('HelpMe', 'I need some help');
Dic.Add('Dumb', 'Yes I know this example is dumb');
{ I want to do the following but do it in sorted order by Enum.Key }
for Enum in Dic do
some processing with Enum.Key and Enum.Value;
Dic.Free;
end;
Run Code Online (Sandbox Code Playgroud)
所以我想按顺序处理我的字典:Dumb,Early,HelpMe,Tired.
不幸的是,Delphi帮助在描述一般的枚举器和TEnumerator如何具体工作方面是非常小的,并没有给出我能找到的例子.关于在Delphi中使用带有泛型的枚举器,网上也很少写. …
我很困惑.在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如何做到这一点? …
我大体上同意,在程序的主要版本应该是1.0,2.0...而显著的更新应该是:1.1,1.2,...,和漏洞修复应该是在第三级:1.0.1,1.0.2,... 1.0.156(如果你去过受版本之间的许多错误修复版本的困扰.
但是现在我想发布我的第一个测试版,它将是导致版本发布的一系列Betas之一1.0.
具体来说,对我而言,将我的Beta版本编号大于我正在开发的编号,例如1.0.1最多1.0.15(如果我有15个测试版),然后跟随它,对我没有意义1.0.
但是使用少于数字的数字1.0似乎很尴尬,例如0.9.1...... 0.9.15如果我开始使用1.9.1... 1.9.15作为版本的Betas ,将会引起混淆2.0.
仅供参考,在您的帮助和更多信息的良好链接之后,这就是我决定的.
对于我的alpha版本,我一直在0.7,0.8,0.9,0.91 ......高达0.98.
我知道我可以做1.0 beta 1,这是"标准"方式.但考虑到所有因素,我将使用:0.99 beta 1,0.99 beta 2 ......在我发布1.0之前.
如果我预先发布我的2.0版本,我可能会按照这种模式称之为1.99 beta 1,1.99 beta 2等.
希望这个问题和答案将帮助您决定您的计划.
我真的想知道我是否遗漏了我正在开发的软件中的任何明显内容.
大多数软件中经常缺少您认为重要的用户界面功能?
一年前我将程序从Delphi 4转换为Delphi 2009,主要是为了跳转到Unicode,同时也获得了Delphi多年来改进的好处.
我的代码当然是所有遗留代码.它使用短字符串,现在已经很方便地变成了长Unicode字符串,并且我已经将所有旧的ANSI函数更改为新的等效函数.
但是在Delphi 2009中,他们引入了TStringBuilder类,可能是在StringBuilder类.NET之后建模的.
我的程序执行了大量的字符串处理和操作,并且可以同时将数百兆字节的大字符串加载到内存中.
我不太了解Delphi的TStringBuilder实现,但我听说它的一些操作比使用默认字符串操作更快.
我的问题是我是否值得通过努力并将我的标准字符串转换为使用TStringBuilder类.这样做我会得到什么和失去什么?
感谢您的回答并引导我得出结论,除非需要.NET兼容性,否则不要打扰.
在他关于Delphi 2009 String Performance的博客中,Jolyon Smith说:
但它看起来好像TStringBuilder主要作为.NET兼容性工具,而不是为Win32应用程序的开发人员提供任何真正的好处,可能除了希望或需要单一来源Win32/.NET代码库的开发人员字符串处理性能不是一个问题.
我希望为用户添加用于将插件编写到我在Delphi中开发的程序的功能.该程序是单个可执行文件,没有使用DLL.
这将允许用户社区编写我的程序的扩展来访问内部数据并添加他们可能觉得有用的功能.
我看过帖子:添加插件功能的建议?但它的答案似乎无法转移到Delphi程序.
我希望,如果可能的话,添加此功能并将我的应用程序保留为单个可执行文件,而不需要任何DLL或其他模块.
您是否知道任何建议如何在Delphi中做到最好的资源,组件或文章,或者您有自己的建议吗?
在我的程序中,我正在编写一封电子邮件,使用安装在用户计算机上的默认电子邮件客户端软件进行发送.
我已经写了mailto地址,主题,多字体,我有几个附件要包括在内.
我几乎使用mailto和ShellExecute工作如下:
Message := 'mailto:someone@somewhere.com'
+ '?subject=This is the subjectBehold Error Report'
+ '&body=This is line 1' + '%0D%0A'
+ 'This is line 2' + '%0D%0A'
+ 'This is line 3'
+ '&Attach=c:\file1.txt';
RetVal := ShellExecute(Handle, 'open', PChar(Message), nil, nil, SW_SHOWNORMAL);
if RetVal <= 32 then
MessageDlg('Cannot find program to send e-mail.', mtWarning, [mbOK], 0);
Run Code Online (Sandbox Code Playgroud)
在Windows Vista计算机上使用Delphi 2009,这将打开Microsoft Mail"创建邮件"窗口,正确填充"收件人","主题"和"正文".但是文件没有附加.
当我研究这个时,我注意到一些评论说这种技术不适用于所有邮件客户端.然而,大多数评论都相当陈旧,因为我意识到这是一种非常古老的技术.
然后我发现Zarko Gajic说 "这种方法没问题,但是你无法以这种方式发送附件".
我看过还有Windows Simple Mail API(MAPI),但Zarko说只有最终用户拥有符合MAPI标准的电子邮件软件才有效.有关使用MAPI和Delphi的文档很好(例如使用mapi发送电子邮件),但他们都有免责声明MAPI并不总是与Windows一起安装.
此外,我真的希望在用户的默认电子邮件程序中首先显示该消息,因此他们将其作为其电子邮件记录的一部分,并且他们可以编辑它并决定是否以及何时发送它.我不确定MAPI是如何工作的,如果它会这样做.
所以我的要求是:
将电子邮件发送到用户的邮件程序中.
允许一个或多个附件.
在XP上(即XP,Vista或7)使用任何Windows机器上的所有电子邮件客户端(希望如此).
有这样的动物吗?或者也许有人知道如何使用mailto/ShellExecute技术获取附件?
大多数人做什么?
编辑:
MAPI解决方案甚至是Indy解决方案都有一些答案. …
delphi ×8
delphi-2009 ×4
aqtime ×1
attachment ×1
email ×1
exception ×1
generics ×1
ide ×1
mailto ×1
optimization ×1
parsing ×1
plugins ×1
shellexecute ×1
tdictionary ×1
token ×1
unicode ×1
usability ×1