Was ist der Unterschied zwischen CGFloat und Float?
169
Ich neige dazu, CGFloat überall zu verwenden, aber ich frage mich, ob ich damit einen sinnlosen "Performance-Hit" bekomme. CGFloat scheint etwas "schwerer" als Float zu sein, oder? An welchen Stellen sollte ich CGFloat verwenden und was macht wirklich den Unterschied?
Wie @weichsel sagte, ist CGFloat nur ein typedef für entweder floatoder double. Sie können sich selbst davon überzeugen, indem Sie bei Xcode mit dem Befehl auf "CGFloat" doppelklicken. Es wird zum CGBase.h-Header gesprungen, in dem das typedef definiert ist. Der gleiche Ansatz wird auch für NSInteger und NSUInteger verwendet.
Diese Typen wurden eingeführt, um das Schreiben von Code zu vereinfachen, der sowohl mit 32-Bit als auch mit 64-Bit ohne Änderungen funktioniert. Wenn Sie jedoch nur floatPräzision in Ihrem eigenen Code benötigen , können Sie diese weiterhin verwenden, floatwenn Sie möchten - dies reduziert Ihren Speicherbedarf etwas. Gleiches gilt für ganzzahlige Werte.
Ich schlage vor, Sie investieren die bescheidene Zeit, die erforderlich ist, um Ihre App 64-Bit sauber zu machen, und versuchen, sie als solche auszuführen, da die meisten Macs jetzt 64-Bit-CPUs haben und Snow Leopard vollständig 64-Bit ist, einschließlich des Kernels und der Benutzeranwendungen. Apples 64-Bit-Übergangshandbuch für Kakao ist eine nützliche Ressource.
Ich glaube, ich verstehe es jetzt. Aber auf dem iPhone scheint es nicht viel zu bedeuten, oder?
4
Auf dem iPhone, wie wir es kennen, nein. Es ist jedoch immer ratsam, zukunftssicheren Code zu verwenden, und dies würde es einfacher machen, denselben Code sicher für OS X wiederzuverwenden.
Quinn Taylor
Sie sagen also im Grunde, NIEMALS direkt ein Float oder Double verwenden, da Sie seitdem an die Prozessorarchitektur gebunden wären (und ich dachte, schnelle JVMs wurden vor Jahren gelöst :)). Welche Grundelemente sind also sicher? int?
Dan Rosenstark
9
Ich habe nicht gesagt, NIEMALS ein Primitiv direkt zu verwenden. Es gibt Zeiten, in denen gerade Grundelemente problematisch sein können, z. B. wenn eine Variable möglicherweise zum Speichern von Daten verwendet wird, die überlaufen könnten, z. B. bei 64-Bit. Im Allgemeinen ist die Verwendung von architekturabhängigen Typedefs sicherer, da Code in einer anderen Architektur weniger wahrscheinlich explodiert. Manchmal kann die Verwendung eines 32-Bit-Typs jedoch völlig sicher sein und Speicherplatz sparen. Die Größe von Grundelementen ist in einer JVM möglicherweise weniger problematisch, aber Obj-C und C werden kompiliert, und das Mischen von 32- und 64-Bit-Bibliotheken und -Code ist in der Tat problematisch.
Quinn Taylor
1
@QuinnTaylor Können Sie ein praktisches Beispiel dafür geben, wie Float überlaufen würde, während CGFloat dies nicht tun würde? Sowohl float als auch CGFloat haben eine endliche Anzahl von Bits. Sie können beide überlaufen lassen, indem Sie mehr Bits speichern müssen, als sie aufnehmen können.
Pwner
76
CGFloat ist ein regulärer Float auf 32-Bit-Systemen und ein Double auf 64-Bit-Systemen
Nun, Sie verwenden doppelt so viel Speicher, wenn Sie sich Sorgen um den Speicher machen.
Tyler
8
Nur auf 64-Bit.
Quinn Taylor
13
Richtig, iPhone OS ist 32-Bit. Wenn Sie darüber nachdenken, drängt das iPhone weder auf die 4-GB-RAM-Beschränkung von 32-Bit, noch verwendet es einen Intel-Prozessor (für den 64-Bit schneller als 32-Bit ist). Außerdem wird Modern Runtime verwendet (im Gegensatz zu Legacy Runtime von 32-Bit auf dem Desktop - suchen Sie SO nach diesen Begriffen, wenn Sie neugierig sind), damit es im Grunde alles kann, was 64-Bit OS X kann. Vielleicht werden wir eines Tages ein Gerät sehen, auf dem das iPhone OS ausgeführt wird und das 64-Bit ist, aber derzeit gibt es keines.
Quinn Taylor
23
Geben Sie ein: das iPhone 5S
dgund
7
5S ist jetzt in 64 Bit. Als ich das letzte Mal an der Konferenz (London) teilgenommen habe, haben sie gesagt, dass die Ausführung von 32-Bit-Apps auf ios7 darin besteht, einen weiteren gemeinsam genutzten Cache-Pool im Speicher zu initiieren, was insgesamt zu mehr Speicherplatz führen kann. Es lohnt sich also auf jeden Fall, alles auf 64-Bit umzustellen. (es sei denn, Sie möchten noch 5.1+ oder 6.0+ unterstützen)
phil88530
2
Wie andere bereits gesagt haben, ist CGFloat ein Float auf 32-Bit-Systemen und ein Double auf 64-Bit-Systemen. Die Entscheidung dazu wurde jedoch von OS X übernommen, wo sie auf den Leistungsmerkmalen früherer PowerPC-CPUs beruhte. Mit anderen Worten, Sie sollten nicht denken, dass float für 32-Bit-CPUs und double für 64-Bit-CPUs gilt. (Ich glaube, Apples ARM-Prozessoren waren in der Lage, Doubles zu verarbeiten, lange bevor sie 64-Bit wurden.) Der größte Leistungseinbruch bei der Verwendung von Doubles besteht darin, dass sie den doppelten Speicher belegen und daher möglicherweise langsamer sind, wenn Sie viele Gleitkommaoperationen ausführen .
Wobei __LP64__angibt, ob die aktuelle Architektur * 64-Bit ist.
Beachten Sie, dass 32-Bit-Systeme weiterhin 64-Bit verwenden doublekönnen. Es dauert lediglich mehr Prozessorzeit. CoreGraphics tut dies daher zu Optimierungszwecken und nicht aus Kompatibilitätsgründen. Wenn Sie sich nicht um die Leistung, sondern um die Genauigkeit sorgen, verwenden Sie einfach double.
Schnell
In Swift gibt CGFloates einen structWrapper entweder Floatfür 32-Bit-Architekturen oder Doublefür 64-Bit -Architekturen (Sie können dies zur Laufzeit oder zur Kompilierung mit erkennen CGFloat.NativeType).
publicstructCGFloat{#ifarch(i386)||arch(arm)/// The native type used to store the CGFloat, which is Float on/// 32-bit architectures and Double on 64-bit architectures.publictypealiasNativeType=Float#elseif arch(x86_64)||arch(arm64)/// The native type used to store the CGFloat, which is Float on/// 32-bit architectures and Double on 64-bit architectures.publictypealiasNativeType=Double#endif
Erwähnen Sie einfach das - Jan, 2020 Xcode 11.3 / iOS13
Swift 5
Aus dem CoreGraphics-Quellcode
publicstructCGFloat{/// The native type used to store the CGFloat, which is Float on/// 32-bit architectures and Double on 64-bit architectures.public typealias NativeType=Double
int
?CGFloat ist ein regulärer Float auf 32-Bit-Systemen und ein Double auf 64-Bit-Systemen
Sie erhalten also keine Leistungseinbußen.
quelle
Wie andere bereits gesagt haben, ist CGFloat ein Float auf 32-Bit-Systemen und ein Double auf 64-Bit-Systemen. Die Entscheidung dazu wurde jedoch von OS X übernommen, wo sie auf den Leistungsmerkmalen früherer PowerPC-CPUs beruhte. Mit anderen Worten, Sie sollten nicht denken, dass float für 32-Bit-CPUs und double für 64-Bit-CPUs gilt. (Ich glaube, Apples ARM-Prozessoren waren in der Lage, Doubles zu verarbeiten, lange bevor sie 64-Bit wurden.) Der größte Leistungseinbruch bei der Verwendung von Doubles besteht darin, dass sie den doppelten Speicher belegen und daher möglicherweise langsamer sind, wenn Sie viele Gleitkommaoperationen ausführen .
quelle
Ziel c
Aus dem Foundation-Quellcode in CoreGraphics
CGBase.h
:Copyright (c) 2000-2011 Apple Inc.
Dies ist im Wesentlichen zu tun:
Wobei
__LP64__
angibt, ob die aktuelle Architektur * 64-Bit ist.Beachten Sie, dass 32-Bit-Systeme weiterhin 64-Bit verwenden
double
können. Es dauert lediglich mehr Prozessorzeit. CoreGraphics tut dies daher zu Optimierungszwecken und nicht aus Kompatibilitätsgründen. Wenn Sie sich nicht um die Leistung, sondern um die Genauigkeit sorgen, verwenden Sie einfachdouble
.Schnell
In Swift gibt
CGFloat
es einenstruct
Wrapper entwederFloat
für 32-Bit-Architekturen oderDouble
für 64-Bit -Architekturen (Sie können dies zur Laufzeit oder zur Kompilierung mit erkennenCGFloat.NativeType
).Aus dem CoreGraphics-Quellcode in
CGFloat.swift.gyb
:* Insbesondere
long
s und Zeiger, daher dieLP
. Siehe auch: http://www.unix.org/version2/whatsnew/lp64_wp.htmlquelle
Erwähnen Sie einfach das - Jan, 2020 Xcode 11.3 / iOS13
Swift 5
Aus dem CoreGraphics-Quellcode
quelle