我目前正在编写一个C#应用程序,它执行大量的数字信号处理,这涉及许多小的微调内存xfer操作.我使用不安全的指针编写了这些例程,它们的表现似乎比我初想的要好得多.但是,我希望应用程序尽可能快.
我可以通过用C或C++重写这些例程来获得任何性能优势,还是应该坚持使用不安全的指针?我想知道与C/C++相比,性能方面的不安全指针会给表带来什么.
编辑:我在这些例程中没有做任何特别的事情,只是正常的DSP事情:缓存友好的数据传输从一个阵列到另一个阵列,在这个过程中有很多乘法,加法,位移等.我希望C/C++例程与它们的C#对应物看起来几乎相同(如果不相同).
编辑:非常感谢大家的所有聪明的答案.我所学到的是,除非进行某种SSE优化,否则我只会通过直接端口获得性能上的任何显着提升.假设所有现代C/C++编译器都可以利用它,我期待着尝试一下.如果有人对结果感兴趣,请告诉我,我会将它们发布到某个地方.(可能需要一段时间).
我一直在尝试编写自己的弱/强指针,但我并不清楚这种关系.我似乎遇到的所有事情都没有明确表达,而且通常一个文档会对另一个文档所说的内容进行谴责.任何人都可以详细解释弱/强指针关系,可能还有一个图像或代码示例?
(请不要只是告诉我"使用提升"或"使用tr1"等.这不是功课,我想学习).
为什么每次运行应用程序时字符串指针的位置都不同,当我使用StringBuilder时,当我声明变量时,它是相同的?
void Main()
{
string str_01 = "my string";
string str_02 = GetString();
unsafe
{
fixed (char* pointerToStr_01 = str_01)
{
fixed (char* pointerToStr_02 = str_02)
{
Console.WriteLine((Int64)pointerToStr_01);
Console.WriteLine((Int64)pointerToStr_02);
}
}
}
}
private string GetString()
{
StringBuilder sb = new StringBuilder();
sb.Append("my string");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
输出:
40907812
178488268
下次:
40907812
179023248
下次:
40907812
178448964
我正在尝试从此转换以下Objective-C代码(源代码)
-(CGRect) dimensionsForAttributedString: (NSAttributedString *) asp {
CGFloat ascent = 0, descent = 0, width = 0;
CTLineRef line = CTLineCreateWithAttributedString( (CFAttributedStringRef) asp);
width = CTLineGetTypographicBounds( line, &ascent, &descent, NULL );
// ...
}
Run Code Online (Sandbox Code Playgroud)
进入斯威夫特:
func dimensionsForAttributedString(asp: NSAttributedString) -> CGRect {
let ascent: CGFloat = 0
let descent: CGFloat = 0
var width: CGFloat = 0
let line: CTLineRef = CTLineCreateWithAttributedString(asp)
width = CTLineGetTypographicBounds(line, &ascent, &descent, nil)
// ...
}
Run Code Online (Sandbox Code Playgroud)
但我&ascent在这一行得到错误:
width = CTLineGetTypographicBounds(line, &ascent, &descent, …Run Code Online (Sandbox Code Playgroud) 我试图SecItemCopyMatching在我的钥匙串实用程序类中调用,以便从钥匙串中获取数据,但我遇到了获取result参数的问题,UnsafeMutablePointer<CFTypeRef?>.
最初的声明(在Swift 2中,在迁移到Swift 3之前)是
// query is a dictionary of [String : AnyObject]
var result: Data?
let status = withUnsafeMutablePointer(to: &result) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
Run Code Online (Sandbox Code Playgroud)
但是在Swift 3中,您现在需要调用.withMemoryRebound才能查看内存.基于Xcode告诉你的事情,我尝试了这个
var result: Data?
let status = withUnsafeMutablePointer(to: &result){
$0.withMemoryRebound(to: Data.self, capacity: 1){
SecItemCopyMatching(query as CFDictionary, UnsafePointer($0))
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这样做,我得到一个错误
无法将类型'
UnsafePointer<_>'的值转换为预期的参数类型'UnsafeMutablePointer<CFTypeRef?>?'
所以,我尝试使用CFTypeRef而不是Data
var result: CFTypeRef?
let status = withUnsafeMutablePointer(to: &result){
$0.withMemoryRebound(to: CFTypeRef.self, capacity: 1){
SecItemCopyMatching(query as CFDictionary, …Run Code Online (Sandbox Code Playgroud) unsafe-pointers core-foundation swift swift3 unsafemutablepointer
在 Swift 2.2 中,我能够将nil有效参数作为有效参数传入一个需要UnsafePointer<UInt8>. 在 Swift 3 中,我不能再这样做了:
func myFuncThatTakesAPointer(buffer: UnsafePointer<UInt8>, length: Int) { /** **/ }
myFuncThatTakesAPointer(buffer: nil, length: 0)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Playground execution failed: error: Xcode8Playground-iOS.playground:62:33: error: nil is not compatible with expected argument type 'UnsafePointer<UInt8>' myFuncThatTakesAPointer(buffer: nil, length: 0) ^
我现在是否需要将函数中的指针声明指定为可选?
我一直在说这形成了CGPoint的C数组:
let arr = UnsafeMutablePointer<CGPoint>.allocate(capacity:4)
defer {
arr.deinitialize()
arr.deallocate(capacity:4)
}
arr[0] = CGPoint(x:0,y:0)
arr[1] = CGPoint(x:50,y:50)
arr[2] = CGPoint(x:50,y:50)
arr[3] = CGPoint(x:0,y:100)
Run Code Online (Sandbox Code Playgroud)
现在(雨燕4.1在Xcode 9.3测试版)两种deinitialize,并deallocate(capacity:)已被弃用。看来我现在应该说的是:
defer {
arr.deinitialize(count:4)
arr.deallocate()
}
Run Code Online (Sandbox Code Playgroud)
那正确吗?
考虑这个将对象序列化为十六进制字符串的扩展:NSDataNSData
Run Code Online (Sandbox Code Playgroud)extension NSData { func base16EncodedString(uppercase uppercase: Bool = false) -> String { let buffer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count: self.length) let hexFormat = uppercase ? "X" : "x" let formatString = "%02\(hexFormat)" let bytesAsHexStrings = buffer.map { String(format: formatString, $0) } return bytesAsHexStrings.joinWithSeparator("") } }
如果 anUnsafeBufferPointer是非拥有指针,这是否意味着我不需要(或无法)显式调用 destroy?如果我UnsafePointer从对象字节的内存中创建一个NSData指针,我是否需要确保在复制缓冲区后销毁该指针?
我想调用Posix套接字函数socket和bindSwift.socket很容易 - 它需要Int32s,但是bind导致问题,因为我有一个sockaddr_in指针,但它需要一个sockaddr指针.在C中,这将是一个演员,如:
bind(sock, (struct sockaddr *)&sockAddress, sizeof(sockAddress))
Run Code Online (Sandbox Code Playgroud)
这是Swift的一次尝试:
let sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
var sockAddress = sockaddr_in()
bind(sock, &sockAddress, UInt32(MemoryLayout<sockaddr_in>.size))
Run Code Online (Sandbox Code Playgroud)
该bind行无法编译:无法将'sockaddr_in'类型的值转换为预期的参数类型'sockaddr'
如何投射指针?
分析一些代码:
static volatile UCHAR *pucSndBufferCur;
eMBErrorCode eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
{
if( eRcvState == STATE_RX_IDLE )
{
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
pucSndBufferCur[0] = ucSlaveAddress;
Run Code Online (Sandbox Code Playgroud)
看起来不安全,如果地址中的内存(pucFrame - 1)已用于其他变量并覆盖它可能会导致故障.
您怎么看?这样的代码可以使用还是错误的方式,永远不应该使用?
unsafe-pointers ×10
swift ×6
pointers ×3
swift3 ×3
c# ×2
c++ ×2
c ×1
ios ×1
memory ×1
objective-c ×1
performance ×1
swift4.1 ×1