Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid string StartsWith and EndsWith #2142

Merged
merged 1 commit into from
Nov 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/kOS.Safe/Compilation/Opcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,14 +1420,14 @@ public static int StaticExecute(ICpu cpu, bool direct, object destination, bool
if (functionPointer is string || functionPointer is StringValue)
{
string functionName = functionPointer.ToString();
if (functionName.EndsWith("()"))
if (StringUtil.EndsWith(functionName, "()"))
functionName = functionName.Substring(0, functionName.Length - 2);
if (!(cpu.BuiltInExists(functionName)))
{
// It is not a built-in, so instead get its value as a user function pointer variable, despite
// the fact that it's being called AS IF it was direct.
if (!functionName.EndsWith("*")) functionName = functionName + "*";
if (!functionName.StartsWith("$")) functionName = "$" + functionName;
if (!StringUtil.EndsWith(functionName, "*")) functionName = functionName + "*";
if (!StringUtil.StartsWith(functionName, "$")) functionName = "$" + functionName;
functionPointer = cpu.GetValue(functionName);
}
}
Expand Down Expand Up @@ -1482,7 +1482,7 @@ public static int StaticExecute(ICpu cpu, bool direct, object destination, bool
// might want to change that.
var name = functionPointer as string;
string functionName = name;
if (functionName.EndsWith("()"))
if (StringUtil.EndsWith(functionName, "()"))
functionName = functionName.Substring(0, functionName.Length - 2);
cpu.CallBuiltinFunction(functionName);

Expand Down
6 changes: 3 additions & 3 deletions src/kOS.Safe/Execution/CPU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ private void SaveAndClearPointers()
// IP jump location for subprograms.
// IP jump location for functions.
savedPointers = new VariableScope(0, null);
var pointers = new List<KeyValuePair<string, Variable>>(globalVariables.Locals.Where(entry => entry.Key.Contains('*')));
var pointers = new List<KeyValuePair<string, Variable>>(globalVariables.Locals.Where(entry => StringUtil.EndsWith(entry.Key, "*")));

foreach (var entry in pointers)
{
Expand Down Expand Up @@ -720,7 +720,7 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool
// In the case where we were looking for a function pointer but didn't find one, and would
// have failed with exception, then it's still acceptable to find a hit that isn't a function
// pointer (has no trailing asterisk '*') but only if it's a delegate of some sort:
if (identifier[identifier.Length - 1] == '*')
if (StringUtil.EndsWith(identifier, "*"))
{
string trimmedTail = identifier.TrimEnd('*');
Variable retryVal = GetVariable(trimmedTail, barewordOkay, failOkay);
Expand All @@ -744,7 +744,7 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool
/// <param name="overwrite">true if it's okay to overwrite an existing variable</param>
public void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false)
{
if (identifier[0] != '$')
if (!StringUtil.StartsWith(identifier, "$"))
{
identifier = "$" + identifier;
}
Expand Down
51 changes: 51 additions & 0 deletions src/kOS.Safe/Utilities/StringUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
namespace kOS.Safe
{
/// <summary>
/// String utility functions that avoid the culture-aware overhead of the builtin string functions.
/// </summary>
public static class StringUtil
{
public static bool EndsWith(string str, string suffix)
{
int strLen = str.Length;
int suffixLen = suffix.Length;

if (strLen < suffixLen)
{
return false;
}

for (int i = 0; i < suffixLen; i++)
{
if (str[strLen - i - 1] != suffix[suffixLen - i - 1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to switch to counting this forward to save some math. (set index to strLen - i - 1 at first, then just increment it by +1 each iteration).

{
return false;
}
}

return true;
}

public static bool StartsWith(string str, string prefix)
{
int strLen = str.Length;
int prefixLen = prefix.Length;

if (strLen < prefixLen)
{
return false;
}

for (int i = 0; i < prefixLen; i++)
{
if (str[i] != prefix[i])
{
return false;
}
}

return true;
}
}
}
3 changes: 2 additions & 1 deletion src/kOS.Safe/kOS.Safe.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
<Compile Include="Function\Persistence.cs" />
<Compile Include="Function\Suffixed.cs" />
<Compile Include="Function\Trigonometry.cs" />
<Compile Include="Utilities\StringUtil.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Compilation\CompiledObject-doc.md" />
Expand Down Expand Up @@ -315,4 +316,4 @@
-->
<ItemGroup />
<ItemGroup />
</Project>
</Project>