- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的任务是从二进制文字 0x0 上的数据库表中拆分多个运行的 varbinary(8000) 列。但是,这可能会改变,所以我想保留这个变量。我想使用 SQLCLR 作为流式表值函数快速执行此操作。我知道我的每个字符串总是至少有几千个字节。
编辑:我更新了我的算法。为了避免内循环展开的麻烦。但是要说服 CLR 对寄存器分配做出正确的选择是极其困难的。如果有一种简单的方法可以让 CLR 相信 j 和 i 真的是同一个东西,那就太棒了。但相反,它确实做了一些愚蠢的事情。优化第一个路径循环会很好。但是您不能在循环中使用 goto。
我决定采用 C 函数 memchr 的 64 位实现。基本上不是一次扫描一个字节并进行比较,我使用一些位旋转一次扫描 8 个字节。作为引用,Array.IndexOf<Byte>
为一个答案做类似 4 字节扫描的事情,我只想继续这样做。 有几点需要注意:
内存压力是 SQLCLR 函数中一个非常现实的问题。 String.Split
已经出来了,因为它预先分配了很多我真的很想避免的内存。它也适用于 UCS-2 字符串,这需要我将我的 ascii 字符串转换为 unicode 字符串,因此在返回时将我的数据视为 lob 数据类型。 (SqlChars
/SqlString
在变成lob类型前只能返回4000字节)。
我想直播。避免String.Split
的另一个原因它一次完成所有工作,造成很大的内存压力。在包含大量定界符的代码上,纯 T-SQL 方法将开始击败它。
我想保持它“安全”。所以都管理好了。安检好像有很大的罚款。
Buffer.BlockCopy
真的很快,而且似乎最好先支付一次费用,而不是不断支付 BitConverter 的费用。这也比将我的输入转换为字符串并保留该引用更便宜。
代码非常快,但似乎我要为很多绑定(bind)检查付费,在初始循环和关键部分找到匹配项时。由于代码中有很多定界符,我倾向于输给一个更简单的 C# 枚举器,它只进行字节比较。
这是我的代码,
class SplitBytesEnumeratorA : IEnumerator
{
// Fields
private readonly byte[] _bytes;
private readonly ulong[] _longs;
private readonly ulong _comparer;
private readonly Record _record = new Record();
private int _start;
private readonly int _length;
// Methods
internal SplitBytesEnumeratorA(byte[] bytes, byte delimiter)
{
this._bytes = bytes;
this._length = bytes.Length;
// we do this so that we can avoid a spillover scan near the end.
// in unsafe implementation this would be dangerous as we potentially
// will be reading more bytes than we should.
this._longs = new ulong[(_length + 7) / 8];
Buffer.BlockCopy(bytes, 0, _longs, 0, _length);
var c = (((ulong)delimiter << 8) + (ulong)delimiter);
c = (c << 16) + c;
// comparer is now 8 copies of the original delimiter.
c |= (c << 32);
this._comparer = c;
}
public bool MoveNext()
{
if (this._start >= this._length) return false;
int i = this._start;
var longs = this._longs;
var comparer = this._comparer;
var record = this._record;
record.id++;
// handle the case where start is not divisible by eight.
for (; (i & 7) != 0; i++)
{
if (i == _length || _bytes[i] == (comparer & 0xFF))
{
record.item = new byte[(i - _start)];
Buffer.BlockCopy(_bytes, _start, record.item, 0, i - _start);
_start = i + 1;
return true;
}
}
// main loop. We crawl the array 8 bytes at a time.
for (int j=i/8; j < longs.Length; j++)
{
ulong t1 = longs[j];
unchecked
{
t1 ^= comparer;
ulong t2 = (t1 - 0x0101010101010101) & ~t1;
if ((t2 & 0x8080808080808080) != 0)
{
i =j*8;
// make every case 3 comparison instead of n. Potentially better.
// This is an unrolled binary search.
if ((t2 & 0x80808080) == 0)
{
i += 4;
t2 >>= 32;
}
if ((t2 & 0x8080) == 0)
{
i += 2;
t2 >>= 16;
}
if ((t2 & 0x80) == 0)
{
i++;
}
record.item = new byte[(i - _start)];
// improve cache locality by not switching collections.
Buffer.BlockCopy(longs, _start, record.item, 0, i - _start); _start = i + 1;
return true;
}
}
// no matches found increment by 8
}
// no matches left. Let's return the remaining buffer.
record.item = new byte[(_length - _start)];
Buffer.BlockCopy(longs, _start, record.item, 0, (_length - _start));
_start = _bytes.Length;
return true;
}
void IEnumerator.Reset()
{
throw new NotImplementedException();
}
public object Current
{
get
{
return this._record;
}
}
}
// We use a class to avoid boxing .
class Record
{
internal int id;
internal byte[] item;
}
最佳答案
跳出框框思考,您是否考虑过将字符串转换为 XML 并使用 XQuery 进行拆分?
例如,您可以传入分隔符和(空气代码):
DECLARE @xml as xml
DECLARE @str as varchar(max)
SET @str = (SELECT CAST(t.YourBinaryColumn AS varchar(max) FROM [tableName] t)
SET @xml = cast(('<X>'+replace(@str,@delimiter,'</X><X>')+'</X>') as xml)
这会将二进制文件转换为字符串并将分隔符替换为 XML 标记。然后:
SELECT N.value('.', 'varchar(10)') as value FROM @xml.nodes('X') as T(N)
将获取单个“元素”,即每个分隔符出现之间的数据。
也许这个想法可以按原样使用,或者作为您可以在此基础上构建的催化剂。
关于c# - 如何消除此循环矢量化的数组边界检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23834632/
我编写了一些运行速度很慢的 VBA 代码。我的代码中有一系列不同的循环。我知道循环并不总是处理数据的最有效方式,所以我认为它们是问题所在。我需要有关如何更改或消除循环的想法,以便加快代码的运行时间。
我目前有一个网址:http://testsite.local/search/?q=findme一旦有人查询,我的搜索页面。我使用 mod_rewrite 重写了一些页面,想知道是否可以将其变成一个不错
有人可以帮助我执行一个查询,其中查询的重复元素被删除 Select * from table where APPNAME = 'Ap1' or APPNAME= 'Ap2' 使用 DISTINCT 的
我正在尝试在 ubuntu 上使用以下命令在一个文件夹中查找文件并通过 FFmpeg 提供并输出到另一个文件夹。问题是当它处理输出路径和文件名时,它添加了一个 .像这样的路径:/conversions
这个问题在这里已经有了答案: How can I remove all duplicates so that NONE are left in a data frame? (3 个答案) 关闭 1
我想证明以下定理: Theorem Frobenius (A: Set) (q: Prop) (p: A -> Prop) : (q \/ forall x : A, p x) -> (foral
我有一个 PHP 脚本,它只需要一些数据,将其分隔为制表符分隔格式,将其保存为 .xls 文件,然后为用户提供下载链接。 大多数情况下运行良好,但有些人正在获取导出的 .xls 文件的缓存版本。 我想
我有一个看起来有点像这个可重现代码的数据框,我想删除每列的异常值(在我们的例子中,数据点低于或高于平均值 2.5 个标准偏差)而不删除整个主题/行。 Subj mn + sd * 2.5) | (x
我正在尝试编写一个实现 fmap 的演示。在 Haskell 中与 continuation ,我的代码如下所示: #include #include template using Callba
在此 HighCharts例如,如何消除 xaxis 开始位置与 Jan 的刻度位置之间的差距。 http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-s
重现步骤: 将TPanel添加到新的VCL表单并设置Align = alClient。 将 TSpeedButton 添加到面板,并将一些 bmp 图像分配给 Glyph 属性。 (可选,但更清晰:F
我得到一个 JavaScript 数组,其中包含一定数量(未指定)的各种元素(字符串、数字、 bool 值)。我需要消除字符串和 bool 值。我应该如何处理它?我应该使用typeof吗? 最佳答案
我正在寻找一个公式,可以消除字符串中空格后的空格和无用字符。 我的第一 react 是执行以下操作:=LEFT(A1,FIND("",A1)) 它适用于所有有空格的情况 但是如果单元格中没有空格,我的
我有以下问题:我正在尝试编写一个 Javascript 游戏,并且 Angular 色由箭头键控制。 问题是,当一个人按住按键时,在触发第一个按键和重复的按键之间存在短暂的延迟。 另外,当按下“向右箭
让我们考虑一个集合的集合,以及需要在管道内对内部集合的每个元素执行的操作。 为了简单起见,让它成为一个数组数组,操作简单的打印到屏幕上。为了表达我的问题,让我们还有一个元素不是集合的数组: $Arra
跟进this question关于包含源文件。我包括一个 Chapel 模块,其中包含一个名为 classes.chpl 的文件。 ,但我当前的项目也有一个 classes.chpl 。正确的消歧模式
我想知道如何在英特尔语法中的某些指令中区分标签名称和寄存器名称。例如,call rdx通常意味着间接跳转,但是如果我们在同一个汇编文件中有一个标签rdx怎么办?我相信它可以被解释为直接跳转到 rdx
据我了解,Chrome 会异步运行整个程序,这会导致我的扩展程序在单击后大约 2 秒后打开。有没有办法强制扩展程序显示带有“正在加载”消息的 html 页面,然后完成加载 javascript 并用内
我正在将 CSV 加载到 sqlite 数据库,如下所示: sqlite3 /path/to/output.db /dev/null 或者,您可以自己生成 SQL 命令,以便可以使用 INSERT 或
我的 .cabal 文件的许多节中经常有类似的属性。例如 Library x ... ghc-options: -O2 -Wall -fno-warn-missing-s
我是一名优秀的程序员,十分优秀!