1. Optimized Type Check

I am looking for comments on the following code:
I am trying to optimize this for speed, so reducing the
number of loops, etc. is key.  The type will be
used with very long decimals, so floating number or integers type
checks and conversions can't be used.
For example, this would be valid input:
"11238997598982379827340982309849509860345.23508972345234872347"

Thanks.
Doug Edmunds
----------code starts here----------

--objective: create a TYPE with these characteristics:
-- a sequence containing:
-- only the digits 1-9, optional minus sign, optional decimal point
-- no sequences-within-sequences
--rules for the string:
--1. minus sign, if any, must be in front of digits
--2. there must be at least 1 digit
--3. there must be at most 1 decimal point
--4. there can be no spaces in the string


--Examples
--valid:  "123."  "-23.45"  "666"  ".00004"
--not valid: 123.55      not a string
--not valid: "123-"      minus sign in wrong place
--not valid: "123a45"    contains a character which is not allowed
--not valid: "123.45.67" more than one decimal
--not valid: "- 123.45"  contains a space
--not valid: ""          empty string
--not valid: "-"         no digits
--not valid: {"234", "567"} more than one string

type number_as_string (sequence input)
  integer decimal_points
  sequence valid_elements
  valid_elements = "-.0123456789"

  if length (input) = 0 then  --cannot be empty
    return 0
  end if

-- test for "." and "-" only
  if length (input) = 1 and find(input[1], "-.") then
    return 0
  end if

--do one pass over the string, if possible, for speed

  decimal_points = 0
  for x = 1 to length(input) do
    if not find(input[x], valid_elements) then
      return 0
    end if
    if input[x] = '.' then  -- count the optional decimal
      decimal_points = decimal_points +1
      if decimal_points > 1 then
        return 0
      end if
    end if
    if input[x] = '-' and x > 1 then  --position of optional hyphen
       return 0
    end if
  end for
  return 1
end type

--------------------------
--test-zone

procedure test_run(number_as_string test_value)
   printf(1, "\n%s passed.\n", {test_value})
end procedure


sequence input_pattern

input_pattern = "-123.456"  --<< change this value mercilessly!
--input_pattern = {52,53}  --this also works.
test_run(input_pattern)

new topic     » topic index » view message » categorize

2. Re: Optimized Type Check

My routine is about 1.6 times faster than yours
Timing and speed checks are done below.

Partial signature at bottom.

--Lucius Lamar Hilley III
--  E-mail at luciuslhilleyiii at juno.com
--  I support transferring of files less than 60K.
--  I can Decode both UU and Base64 format.


-->objective: create a TYPE with these characteristics:
--> a sequence containing:
--> only the digits 1-9, optional minus sign, optional decimal point
--> no sequences-within-sequences
-->rules for the string:
-->1. minus sign, if any, must be in front of digits
-->2. there must be at least 1 digit
-->3. there must be at most 1 decimal point
-->4. there can be no spaces in the string

-- 5. "-." is also not valid -- I added this.

-->
-->Thanks.
-->Doug Edmunds


--Examples
--valid:  "123."  "-23.45"  "666"  ".00004"
--not valid: 123.55      not a string
--not valid: "123-"      minus sign in wrong place
--not valid: "123a45"    contains a character which is not allowed
--not valid: "123.45.67" more than one decimal
--not valid: "- 123.45"  contains a space
--not valid: ""          empty string
--not valid: "-"         no digits
--not valid: {"234", "567"} more than one string

type number_as_string (sequence input)
  integer decimal_points, length_
  sequence valid_elements
  valid_elements = "-.0123456789"

  length_ = length(input)
  if length_ = 0 then  --cannot be empty
    return 0
  elsif length_ = 1 then
    if find(input[1], "-.") then
      return 0
    end if
  elsif length_ = 2 then
    if compare(input, "-.") = 0 then
      return 0
    end if
  end if

--do one pass over the string, if possible, for speed

  decimal_points = 0
  for x = 1 to length_ do
    if not find(input[x], valid_elements) then
      return 0
    end if
    if input[x] = '.' then  -- count the optional decimal
      decimal_points = decimal_points +1
      if decimal_points > 1 then
        return 0
      end if
    end if
    if input[x] = '-' and x > 1 then  --position of optional hyphen
       return 0
    end if
  end for
  return 1
end type

type number_as_string2 (sequence input)
  integer length_
  sequence valid

  valid = "-.0123456789"
  length_ = length(input)

  if length_ = 0 then  --cannot be empty
    return 0
  elsif length_ = 1 then
    if find(input[1], "-.") then --cannot have only "-" or "."
      return 0
    end if
  elsif length_ = 2 then
    if compare(input, "-.") = 0 then --cannot be only "-."
      return 0
    end if
  end if

  if find('-', input) > 1 then
    return 0
  end if

  if find('.', input[find('.', input) + 1..length_]) then
    return 0
  end if

  for a = 1 to length_ do
    if find(input[a], valid) = 0 then
      return 0
    end if
  end for
  return 1
end type
--------------------------
--test-zone

procedure test_run(number_as_string test_value)
   --printf(1, "\n%s passed.\n", {test_value})
   test_value = test_value
end procedure

procedure test_run2(number_as_string2 test_value)
   --printf(1, "\n%s passed.\n", {test_value})
   test_value = test_value
end procedure

machine_proc(38, 100)-- tick_rate(100)

atom t, t2
sequence input_pattern

input_pattern = "-123.456"  --<< change this value mercilessly!
--input_pattern = {52,53}  --this also works.
test_run(input_pattern)
test_run2(input_pattern)

input_pattern =
"11238997598982379827340982309849509860345.23508972345234872347"
t = time()
for a = 1 to 15000 do
  test_run(input_pattern)-- your routine buffed up some.
end for
t = time() - t
printf(1, "Yours test time: %d\n", t)

t2 = time()
for a = 1 to 15000 do
  test_run2(input_pattern)--My routine
end for
t2 = time() - t2
printf(1, "My    test time: %d\n", t2)

printf(1, "Times mine faster than yours: %1.2f\n",  t / t2)
printf(1, "Times yours faster than mine: %1.2f\n",  t / t2)
--

--Lucius Lamar Hilley III
--  E-mail at luciuslhilleyiii at juno.com

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu