Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8023525
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T22:35:14+00:00 2026-06-04T22:35:14+00:00

I have some functions to count a substring in a string delimited by spaces:

  • 0

I have some functions to count a substring in a string delimited by spaces:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.SysUtils,windows;

//s=string to search in
//t=string to search for
//cs=delimiters

function f0(const s,t:string;const cs:tsyscharset):integer;
var
  p,q:pchar;
  u:string;
begin
  result:=0;
  p:=pointer(s);
  if p<>nil then
    while p^<>#0 do
    begin
      while (p^<>#0) and charinset(p^,cs) do inc(p);
      q:=p;
      while (p^<>#0) and not charinset(p^,cs) do inc(p);
      if p>q then
      begin
        setstring(u,q,p-q);
        //writeln('[',u,']');
        if u=t then inc(result);
      end;
    end;
end;

function f1(const s,t:string;const cs:tsyscharset):integer;
var
  i,j,l:integer;
  u:string;
begin
  result:=0;
  l:=length(s);
  i:=1;
  while i<=l do
  begin
    while (i<=l) and charinset(s[i],cs) do inc(i);
    j:=i;
    while (i<=l) and not charinset(s[i],cs) do inc(i);
    if i>j then
    begin
      u:=copy(s,j,i-j);
      //writeln('[',u,']');
      if u=t then inc(result);
    end;
  end;
end;

function f2(const s,t:string;const cs:tsyscharset):integer;
var
  i,j,l:integer;
  u:string;
begin
  result:=0;
  l:=length(s);
  i:=1;
  while i<=l do
  begin
    while (i<=l) and charinset(s[i],cs) do inc(i);
    j:=i;
    while (i<=l) and not charinset(s[i],cs) do inc(i);
    if i>j then
    begin
      setlength(u,i-j);
      move(s[j],pointer(u)^,(i-j)*2);
      //writeln('[',u,']');
      if u=t then inc(result);
    end;
  end;
end;

type
  tfunc=function(const s,t:string;const cs:tsyscharset):integer;

const
  s='  de foo   de'+#13+' baz blah de  de blah'+#10+' asd de qwe rtz   un f'+#9+' t de ds w de  ';
  t='de';
  cs=[' ',#13,#10,#9];//CR,LF,TAB
  n=5000000;

procedure time(i:integer;f:tfunc);
var
  j,k:integer;
  start,finish,freq:int64;
begin
  QueryPerformanceCounter(start);
  for j := 1 to n do k:=f(s,t,cs);
  QueryPerformanceCounter(finish);
  QueryPerformanceFrequency(freq);
  Writeln(Format('f%u:%u:%.3fs',[i,k,(finish-start)/freq]));
end;

const
  funcs:array[0..2] of tfunc=(f0,f1,f2);
var
  i:integer;
begin
  setpriorityclass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  for i := low(funcs) to high(funcs) do time(i,funcs[i]);
  readln
end.

The speed results are

f0:7:7,624s
f1:7:8,066s
f2:7:6,454s

My first question is: Why is f2 faster than f0?

My second question is: Do you have an idea how I can optimize this even more (without inline assembler)?

IDE: Delphi XE2 (Unicode)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T22:35:15+00:00Added an answer on June 4, 2026 at 10:35 pm

    Why is it faster? Impossible to guess without a profiler. And it will depend on the CPU you run on.

    I guess the faster will be processed by f2 since SetLength() will avoid reallocation most of the time, whereas SetString() will always release the memory before allocating it. It depends on your case.

    For even faster process, with the same algorithm (you may find something even more optimized), I’d try:

    const
      cs = [32,13,10,9];  
    
    function f2(const s,t:string):integer;
    var
      i,j,l:integer;
    begin
      result := 0;
      l := length(s);
      i := 1;
      while i<=l do
      begin
        while (i<=l) and (ord(s[i]) in cs) do inc(i);
        j:=i;
        while (i<=l) and not(ord(s[i]) in cs) do inc(i);
        if (i>j) and CompareMem(pointer(s[j]),pointer(t),(i-j)*sizeof(char)) then
          inc(result);
      end;
    end;
    

    That is:

    • The CharInSet is not worth it for control chars;
    • Using a static set is IMHO faster than passing a parameter (but you can use a parameter if you want);
    • Do not use a temporary variable (this is the slow part of your algorithm, I think), but a good old CompareMem – there is still room for improvement here.

    You may try writing:

    const 
      cs: set of 0..32 = [32,13,10,9];
    

    Which may be a bit faster, since the generated ASM code will be a fast bit-looking instruction, whereas the first version will use a list of comparison. But I think this won’t make a big difference.

    In all cases, I guess that you should better:

    • Not optimize too early – use first a profiler to guess what is slow and worth rewriting;
    • Optimize with real data, not a simplified fixed set as in your benchmark: you would optimized for one kind of data, whereas it won’t be necessary true with real data.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following code to count and trigger some functions using jQuery: jQuery('#input_guideName').keyup(function(e)
I have the following code: Some functions: A::A(int i_a) {cout<<int Ctor\n;} //conversion constructor void
I have some functions that use opengl to draw lines on the screen (health
i have some functions(charfreq,wordfreq,charcount,wordcount,parerror) and i want to use it in dataStructure with the
I have some concerns related to the fact of testing some functions containing the
In the process of changing some code, I have spilt some functions into multiple
I have written some general functions to convert between decimal and any other base-n
In a RIA Domain service I have added some utility functions. For instance we
In an iPhone application, I have some plain C functions. Is it possible to
I have some code in a couple of different functions that looks something like

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.