我想获得一个byte[]从float[]尽可能快地,不通过整个数组循环(通过铸造,可能).不安全的代码很好.谢谢!
我正在寻找比浮点数组长4倍的字节数组(字节数组的维数将是浮点数组的4倍,因为每个浮点数由4个字节组成).我将它传递给BinaryWriter.
编辑:对那些尖叫"过早优化"的评论家:我在优化之前使用ANTS探查器对此进行了基准测试.速度显着提高,因为该文件具有直写缓存,并且浮点数组的大小恰好与磁盘上的扇区大小相匹配.二进制编写器包装使用pinvoke'd win32 API 创建的文件句柄.优化发生,因为这减少了函数调用的数量.
而且,关于内存,这个应用程序创建了大量使用大量内存的缓存.我可以分配一次字节缓冲区并重复使用它多次 - 在这个特定实例中的双内存使用量相当于应用程序整体内存消耗的舍入误差.
所以我想这里的教训不是做出过早的假设;)
我正在尝试使用一些固定字段来获取不安全结构的字段类型.固定字段FieldType不返回实际类型.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct MyStruct
{
public UInt32 Field1;
public fixed sbyte Field2[10];
public UInt64 Field3;
}
void Test()
{
var theStruct = new MyStruct();
string output = "";
foreach (FieldInfo fi in theStruct.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance))
{
output += fi.Name + ": " + fi.FieldType.ToString() + "\r\n";
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
字段1: System.UInt32
字段2: TestProjectNS.MyStruct+<Field2>e__FixedBuffer0
字段3: System.UInt64
我正在寻找Field2告诉我它sbyte而不是TestProjectNS.MyStruct+<Field2>e__FixedBuffer0
我有一堆方法可以使用不安全的代码直接WriteableBitmap读取WPF 并从中BackBuffer直接读取.
GC.KeepAlive每当我做这样的事情时,我是否应该使用它并不完全清楚:
int MyMethod(WriteableBitmap bmp)
{
return DoUnsafeWork(bmp.BackBuffer);
}
Run Code Online (Sandbox Code Playgroud)
在一方面,仍然要参考bmp上MyMethod的堆栈.另一方面,它似乎依赖于实现细节 - 这可以编译为尾调用,例如,不保留bmp对该时刻的引用DoUnsafeWork.
同样,想象下面的假设代码:
int MyMethod()
{
WriteableBitmap bmp1 = getABitmap();
var ptr = bmp.BackBuffer;
WriteableBitmap bmp2 = getABitmap();
return DoUnsafeWork(ptr, bmp2);
}
Run Code Online (Sandbox Code Playgroud)
理论上,bmp1在方法返回之前,对堆栈的保留的引用,但同样,似乎使用了实现细节.当然编译器可以自由合并bmp1,bmp2因为它们永远不会同时存在,即使编译器从来没有这样做,JITter仍然可以,也可能(例如通过将它们存储在同一个寄存器中,第一个,然后另一个).
所以,一般来说:我应该依赖locals/arguments作为对象的有效引用,还是应该总是GC.KeepAlive用来保证正确性?
这尤其令人费解,因为显然,FxCop认为GC.KeepAlive总是很糟糕.
我想假设这个问题的目的是检查是否至少有一种方法,即使通过最不安全的黑客,仍然保持对非blittable值类型的引用.我知道这种设计类型与犯罪相当; 除了学习之外,我不会在任何实际案例中使用它.因此,请接受现在阅读异常不安全的代码.
我们知道可以以这种方式存储和增加对blittable类型的引用:
unsafe class Foo
{
void* _ptr;
public void Fix(ref int value)
{
fixed (void* ptr = &value) _ptr = ptr;
}
public void Increment()
{
var pointer = (int*) _ptr;
(*pointer)++;
}
}
Run Code Online (Sandbox Code Playgroud)
在安全性方面,上述类别可以与虚空中的跳跃相媲美(没有双关语意),但正如这里已经提到的那样.如果在堆栈上分配的变量传递给它,然后调用方法的作用域终止,则可能会遇到错误或显式访问冲突错误.但是,如果您执行这样的程序:
static class Program
{
static int _fieldValue = 42;
public static void Main(string[] args)
{
var foo = new Foo();
foo.Fix(ref _fieldValue);
foo.Increment();
}
}
Run Code Online (Sandbox Code Playgroud)
在卸载相关应用程序域之前,不会处理该类,因此适用于该字段.老实说,我不知道高频堆中的字段是否可以重新分配,但我个人认为不是.但是现在让我们放弃安全(如果可能的话).在阅读了这个和这些问题后,我想知道是否有办法为非blittable静态类型创建类似的方法,所以我制作了这个程序,它实际上有效.阅读评论以了解它的作用.
static class Program
{
static Action _event;
public static …Run Code Online (Sandbox Code Playgroud) 背景
假设我有一个直接的ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
Run Code Online (Sandbox Code Playgroud)
并假设我将缓冲区传递给AsynchronousSocketChannel以从该套接字读取数据块,一次最多X个字节(此处示例中为1024).
从套接字到直接 ByteBuffer 的传输时间非常棒,因为它全部发生在本机OS内存空间中; 我还没有通过JVM"血脑"屏障......
题
假设我的工作是扫描从直接字节缓冲区读回的所有字节,我这样做的最快方法是什么?
我最初问" ......利用sun.misc.Unsafe "但也许这是错误的假设.
可能的方法
我目前看到三种方法,我最感兴趣的是#3:
我确实认为,假设copyMemory操作正是它所宣传的内容,即使在更优的操作系统空间中,上面的#2方法可能仍然是最优化的,因为我没有在开始处理之前创建缓冲区的重复项它.
这与" 我可以使用不安全迭代字节[]更快吗? "问题不同,因为我甚至没有计划在内部将字节拉入字节[],如果没有必要的话.
谢谢你的时间; 只是好奇,如果有人(彼得?)已经疯狂与不安全做这样的事情.
我有一个小的AngularJS应用程序,我试图打开上传的图像,并遇到角度在URL的开头添加"unsafe:"的问题.我在我的应用配置中添加了以下行来清理URL,但它对我不起作用:
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob:chrome-extension):|data:image|\//);
Run Code Online (Sandbox Code Playgroud)
我正在使用Angular v1.3.0,所以我使用正确的属性名称.我主要使用Chrome,但我在其他浏览器中遇到同样的问题.此外,我的图像的开头看起来像这样:
unsafe:data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUg...
Run Code Online (Sandbox Code Playgroud)
知道我的正则表达式中缺少什么吗?提前致谢!
Java 8增加了三个围栏sun.misc.Unsafe.
看完他们的文档后我感到很困惑.
所以,我在网上搜索,发现了这个链接.
根据上面的页面,我相信这些方法在实践中几乎没有增加任何内容.如果我错了,请纠正我,粗略地说,loadFence(),storeFence()和fullFence()分别对应于volatile read,lazy write和volatile write,尽管技术上这些fences比volatile变量更强.所以loadFence()是一个获取栅栏,而storeFence()是一个释放栅栏,而fullFence()是一个完整的栅栏.
但是,storeFence()的文档看起来很奇怪.
它说,
/**
* Ensures lack of reordering of stores before the fence
* with loads or stores after the fence.
*/
void storeFence();
Run Code Online (Sandbox Code Playgroud)
这看起来不像是一个释放围栏.它应该如何使用?不应该
/**
* Ensures lack of reordering of loads or stores before the fence
* with stores after the fence.
*/
void storeFence();
Run Code Online (Sandbox Code Playgroud)
我之前和以后意味着先前的意思.
编辑
当我说这些"围栏在实践中没有添加任何东西"时,我并不是说"我们不会在通常的开发中使用它们".
我的意思是,即使没有这些方法,我们也可以获得这些"围栏".如果我是正确的,实际上,读取一个虚拟的volatile会产生loadFence()的效果,而写一个虚拟的volatile会产生fullFence()的效果,而unsafe.putOrderedXXX()(或者AtomicInteger.lazySet())会产生效果. storeFence().
它们可能有细微差别,但在目前的实施中,它们是可交换的.(链接暗示似乎)
这就是我所说的"他们没有添加任何新东西".
另一个编辑
这已经修复了.
请参阅https://bugs.openjdk.java.net/browse/JDK-8038978
谢谢@ john-vint
我正在尝试在新的DNX4.6内核上编译程序,但由于以下原因,它无法编译:
error CS0227: Unsafe code may only appear if compiling with /unsafe
这是我的代码:
[CompilerGenerated]
public unsafe class GrayscaleQuantizer : PaletteQuantizer
{
Run Code Online (Sandbox Code Playgroud)
我已经在网上看了,我无法得到与我一样的问题.我无法在项目属性的"构建"选项卡上勾选"允许不安全代码",因为没有选项可以这样做...
有谁知道解决方案?
我需要以下列形式将参数传递给不安全的DllImported函数:
[DllImport("third_party.dll")]
private static extern unsafe int start(int argc, char** argv);
Run Code Online (Sandbox Code Playgroud)
我假设它是一个字符串数组.但是,当我尝试执行以下操作时,我得到'无法从字符串[]转换为char**'错误.我如何让这个工作?谢谢.
string[] argv = new string[] { };
start(0, argv);
Run Code Online (Sandbox Code Playgroud)
编辑1: 问题被标记为重复,但看着可能重复的问题,我仍然没有看到如何使这个工作.
编辑2:进一步确认问题和所需参数.它看起来像您的标准argc/argv参数(参数计数,然后是参数值).与启动ac程序的方式相同:int main(int argc, char** argv); 对于这个特殊问题,我根本不想传递任何参数(因此count为0).
编辑3: 我从第三方库供应商那里获得了更多信息.这里是:
编辑4:使用工作解决方案进行最终编辑(至少在我的情况下).我会把它作为答案,但不能,因为这个问题被标记为重复.这是一个帮助我最多的问题的链接.最后,dll函数需要一个指向带有ANSI字符串的缓冲区的指针数组. 所以我的最终方法(基于相关问题)如下.在内存中创建一个数组来保存指针,然后将每个字符串分配到内存中的其他位置,并在第一个指针数组中写入指向这些字符串的指针.此代码适用于生产:
[DllImport("third_party.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int start(Int32 args, IntPtr argv);
public bool start(params string[] arguments)
{
int result;
if (arguments == null || arguments.Length == 0)
{
result = dll_system_startup(0, IntPtr.Zero);
}
else …Run Code Online (Sandbox Code Playgroud) 我想使用新的Span将非托管数据直接发送到套接字,SocketAsyncEventArgs但似乎SocketAsyncEventArgs只能接受Memory<byte>哪些无法用r byte *或IntPtr 进行初始化.
那么请问有没有办法使用span SocketAsyncEventArgs?
谢谢您的帮助.
unsafe ×10
c# ×7
.net ×2
java ×2
.net-core ×1
angularjs ×1
bytebuffer ×1
char ×1
delegates ×1
dllimport ×1
download ×1
javascript ×1
marshalling ×1
performance ×1
ref ×1
reflection ×1
regex ×1
sockets ×1