- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在构建一个压力测试客户端,它使用客户端可以召集的尽可能多的线程来攻击服务器并分析响应。我经常发现自己受到垃圾收集(和/或缺乏垃圾收集)的限制,在大多数情况下,它归结为我实例化的字符串,只是为了将它们传递给 Regex 或 Xml 解析例程。
如果反编译 Regex 类,您会看到在内部,它使用 StringBuilder 来做几乎所有事情,但您不能传递给它一个字符串生成器;它有助于在开始使用之前深入研究私有(private)方法,因此扩展方法也不会解决它。如果您想从 System.Xml.Linq 中的解析器中获取对象图,您会遇到类似的情况。
这不是迂腐的提前过度优化的情况。我看过 Regex replacements inside a StringBuilder问题和其他。我还分析了我的应用程序以查看上限来自何处,并且现在使用 Regex.Replace()
确实在方法链中引入了显着的开销,我正在尝试使用每小时数百万个请求,并检查 XML 响应中的错误和嵌入式诊断代码。我已经摆脱了几乎所有其他限制吞吐量的低效率问题,而且我什至通过扩展 StringBuilder 来在不需要捕获组或反向引用时执行通配符查找/替换,从而减少了很多 Regex 开销,但在我看来,现在有人已经完成了基于 Regex 和 Xml 解析实用程序的自定义 StringBuilder(或者更好的是 Stream)。
好吧,说完了,但我必须自己做吗?
更新:我找到了一个解决方法,可以将峰值内存消耗从几千兆字节降低到几百兆字节,所以我将其发布在下面。我没有将其添加为答案,因为 a) 我通常讨厌这样做,并且 b) 我仍然想知道是否有人在我之前花时间自定义 StringBuilder 来执行正则表达式(或反之亦然)。
在我的例子中,我无法使用 XmlReader,因为我正在摄取的流在某些元素中包含一些无效的二进制内容。为了解析 XML,我必须清空这些元素。我以前使用单个静态编译的 Regex 实例来进行替换,这会消耗大量内存(我正在尝试处理 ~300 10KB 文档/秒)。大幅减少消耗的变化是:
IndexOf
方法。 WildcardReplace
方法,每次调用允许一个 通配符(* 或?)WildcardReplace()
调用替换了 Regex 用法,以清空违规元素的内容这是非常不漂亮的,并且仅在我自己的目的需要的范围内进行了测试;我本来可以让它更优雅、更强大,但是 YAGNI 之类的,我很着急。这是代码:
/// <summary>
/// Performs basic wildcard find and replace on a string builder, observing one of two
/// wildcard characters: * matches any number of characters, or ? matches a single character.
/// Operates on only one wildcard per invocation; 2 or more wildcards in <paramref name="find"/>
/// will cause an exception.
/// All characters in <paramref name="replaceWith"/> are treated as literal parts of
/// the replacement text.
/// </summary>
/// <param name="find"></param>
/// <param name="replaceWith"></param>
/// <returns></returns>
public static StringBuilder WildcardReplace(this StringBuilder sb, string find, string replaceWith) {
if (find.Split(new char[] { '*' }).Length > 2 || find.Split(new char[] { '?' }).Length > 2 || (find.Contains("*") && find.Contains("?"))) {
throw new ArgumentException("Only one wildcard is supported, but more than one was supplied.", "find");
}
// are we matching one character, or any number?
bool matchOneCharacter = find.Contains("?");
string[] parts = matchOneCharacter ?
find.Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)
: find.Split(new char[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
int startItemIdx;
int endItemIdx;
int newStartIdx = 0;
int length;
while ((startItemIdx = sb.IndexOf(parts[0], newStartIdx)) > 0
&& (endItemIdx = sb.IndexOf(parts[1], startItemIdx + parts[0].Length)) > 0) {
length = (endItemIdx + parts[1].Length) - startItemIdx;
newStartIdx = startItemIdx + replaceWith.Length;
// With "?" wildcard, find parameter length should equal the length of its match:
if (matchOneCharacter && length > find.Length)
break;
sb.Remove(startItemIdx, length);
sb.Insert(startItemIdx, replaceWith);
}
return sb;
}
最佳答案
在这里试试这个。一切都是基于字符的,效率级别相对较低。可以使用任意数量的 *
或 ?
。但是,您的 *
现在是 ✪
而您的 ?
现在是 ★
。大约三天的工作进行了这项工作,以使其尽可能干净。您甚至可以一次输入多个查询!
示例用法:wildcard(new StringBuilder("Hello and welcome"), "hello✪w★l", "be")
结果为“become”。
////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////// Search for a string/s inside 'text' using the 'find' parameter, and replace with a string/s using the replace parameter
// ✪ represents multiple wildcard characters (non-greedy)
// ★ represents a single wildcard character
public StringBuilder wildcard(StringBuilder text, string find, string replace, bool caseSensitive = false)
{
return wildcard(text, new string[] { find }, new string[] { replace }, caseSensitive);
}
public StringBuilder wildcard(StringBuilder text, string[] find, string[] replace, bool caseSensitive = false)
{
if (text.Length == 0) return text; // Degenerate case
StringBuilder sb = new StringBuilder(); // The new adjusted string with replacements
for (int i = 0; i < text.Length; i++) { // Go through every letter of the original large text
bool foundMatch = false; // Assume match hasn't been found to begin with
for(int q=0; q< find.Length; q++) { // Go through each query in turn
if (find[q].Length == 0) continue; // Ignore empty queries
int f = 0; int g = 0; // Query cursor and text cursor
bool multiWild = false; // multiWild is ✪ symbol which represents many wildcard characters
int multiWildPosition = 0;
while(true) { // Loop through query characters
if (f >= find[q].Length || (i + g) >= text.Length) break; // Bounds checking
char cf = find[q][f]; // Character in the query (f is the offset)
char cg = text[i + g]; // Character in the text (g is the offset)
if (!caseSensitive) cg = char.ToLowerInvariant(cg);
if (cf != '★' && cf != '✪' && cg != cf && !multiWild) break; // Break search, and thus no match is found
if (cf == '✪') { multiWild = true; multiWildPosition = f; f++; continue; } // Multi-char wildcard activated. Move query cursor, and reloop
if (multiWild && cg != cf && cf != '★') { f = multiWildPosition + 1; g++; continue; } // Match since MultiWild has failed, so return query cursor to MultiWild position
f++; g++; // Reaching here means that a single character was matched, so move both query and text cursor along one
}
if (f == find[q].Length) { // If true, query cursor has reached the end of the query, so a match has been found!!!
sb.Append(replace[q]); // Append replacement
foundMatch = true;
if (find[q][f - 1] == '✪') { i = text.Length; break; } // If the MultiWild is the last char in the query, then the rest of the string is a match, and so close off
i += g - 1; // Move text cursor along by the amount equivalent to its found match
}
}
if (!foundMatch) sb.Append(text[i]); // If a match wasn't found at that point in the text, then just append the original character
}
return sb;
}
关于c# - 是否有人围绕 StringBuilders 或 Streams 实现了 Regex 和/或 Xml 解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11533110/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!