CGFloat ve float kullanma arasındaki fark nedir?


169

CGFloat'ı her yerde kullanma eğilimindeyim, ama bununla anlamsız bir "performans isabeti" alıp alamayacağımı merak ediyorum. CGFloat şamandıradan daha ağır bir şey gibi görünüyor, değil mi? CGFloat'ı hangi noktalarda kullanmalıyım ve gerçekten farkı yaratan nedir?

Yanıtlar:


193

@Weichsel'in belirttiği gibi, CGFloat ya sadece bir typedef ya floatda double. Xcode'da "CGFloat" komutunu çift tıklatarak kendiniz görebilirsiniz - typedef'in tanımlandığı CGBase.h başlığına atlar. Aynı yaklaşım NSInteger ve NSUInteger için de kullanılır.

Bu türler, değişiklik yapılmadan 32 bit ve 64 bit üzerinde çalışan kod yazmayı kolaylaştırmak için tanıtıldı. Ancak, ihtiyacınız olan tek şey floatkendi kodunuz dahilinde hassassa, yine de kullanabilirsiniz float- bellek ayak izinizi biraz azaltacaktır. Aynısı tamsayı değerler için de geçerlidir.

Uygulamanızın 64 bit temizliğini yapmak ve bu şekilde çalıştırmayı denemek için gereken mütevazı süreyi yatırmanızı öneririm, çünkü çoğu Mac'in artık 64 bit CPU'ları var ve Snow Leopard, çekirdek ve kullanıcı uygulamaları da dahil olmak üzere tamamen 64 bit. Apple'ın Kakao için 64 bit Geçiş Kılavuzu yararlı bir kaynaktır.


Sanırım şimdi anladım. Ama iPhone'da çok önemli değil gibi görünüyor, değil mi?

4
İPhone'da bildiğimiz gibi, hayır. Bununla birlikte, geleceğe hazır kod için her zaman akıllıca olacaktır ve bu, OS X için aynı kodu güvenle yeniden kullanmayı kolaylaştıracaktır.
Quinn Taylor

yani, o zamandan beri işlemci mimarisine bağlı kalacağınızı ASLA doğrudan bir şamandıra veya çift kullanmayın diyorsunuz (ve bu yıl önce hızlı JVM'lerin çözüldüğünü düşündüm :)). Peki hangi ilkeller güvenlidir? int?
Dan Rosenstark

9
ASLA doğrudan bir ilkel kullanmadım demedim. Düz ilkellerin sorunlu olabileceği zamanlar vardır, örneğin 64-bit gibi taşan verileri depolamak için bir değişkenin akla yatkın olarak kullanılabilmesi gibi. Genel olarak, mimariye bağımlı typedefs kullanmak daha güvenlidir, bu kodun farklı bir mimaride patlaması daha az olasıdır. Ancak, bazen 32 bitlik bir tür kullanmak tamamen güvenli olabilir ve size bellek tasarrufu sağlayabilir. İlkellerin boyutu bir JVM'de daha az sorun olabilir, ancak Obj-C ve C derlenir ve 32 ve 64 bit kitaplıkları ve kodu karıştırmak gerçekten sorunludur.
Quinn Taylor

1
@QuinnTaylor, CGFloat yapmazken şamandıranın nasıl taşacağına dair pratik bir örnek verebilir misiniz? Hem float hem de CGFloat sınırlı sayıda bite sahiptir. Her ikisini de taşıyabileceklerinden daha fazla bit saklamak zorunda kalarak taşıyabilirsiniz.
Pwner

76

CGFloat, 32 bit sistemlerde düzenli bir şamandıra ve 64 bit sistemlerde çift

typedef float CGFloat;// 32-bit
typedef double CGFloat;// 64-bit

Böylece herhangi bir performans cezası almazsınız.


3
Eğer bellek konusunda endişeleniyorsanız, iki kat daha fazla bellek kullanırsınız.
Tyler

8
Ancak sadece 64 bit.
Quinn Taylor

13
Doğru, iPhone OS 32 bit. Bunu düşünürseniz, iPhone 32 bitlik 4GB RAM sınırlamasını zorlamıyor veya Intel işlemci (64 bit 32 bit'ten daha hızlı) kullanıyor. Ayrıca, Modern Çalışma Zamanı'nı kullanıyor (masaüstündeki 32 bitlik Eski Çalışma Zamanı'nın aksine - merak ediyorsanız bu terimler için arama yapın), böylece 64 bit OS X'in yapabileceği her şeyi yapabilir. Belki bir gün iPhone OS çalıştıran ve 64 bit olan bir cihaz göreceğiz, ancak şu anda yok.
Quinn Taylor

23
Girin: iPhone 5S
dgund

7
5S şimdi 64 bit, konferansa en son girdiğimde (londra), ios7'de 32 bit uygulamaları çalıştırma şeklinin bellekte başka bir önbellek havuzu başlatmak olduğunu ve bu da genel olarak daha fazla bellek kullanılmasına neden olabileceğini söyledi. bu yüzden onun def her şeyi 64 bit kadar dönüştürmek için değer. (5.1+ veya 6.0+ hala desteklemek istemiyorsanız)
phil88530

2

Diğerlerinin söylediği gibi, CGFloat 32 bit sistemlerde bir şamandıra ve 64 bit sistemlerde bir çifttir. Bununla birlikte, bu karar, erken PowerPC CPU'ların performans özelliklerine dayanılarak verildiği OS X'ten miras alındı. Başka bir deyişle, float'ın 32 bit CPU'lar için olduğunu ve çiftin 64 bit CPU'lar için olduğunu düşünmemelisiniz. (Apple'ın ARM işlemcilerinin 64-bit gitmeden önce iki katını işleyebildiğine inanıyorum.) Çiftleri kullanmanın ana performansı, iki kat bellek kullanması ve bu nedenle çok fazla kayan nokta işlemi yapıyorsanız daha yavaş olabileceğidir. .


2

Objective-C

Temel kaynak kodundan, CoreGraphics'te CGBase.h:

/* Definition of `CGFLOAT_TYPE', `CGFLOAT_IS_DOUBLE', `CGFLOAT_MIN', and
   `CGFLOAT_MAX'. */

#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif

/* Definition of the `CGFloat' type and `CGFLOAT_DEFINED'. */

typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1

Telif Hakkı (c) 2000-2011 Apple Inc.

Bu aslında şunları yapıyor:

#if defined(__LP64__) && __LP64__
typedef double CGFloat;
#else
typedef float CGFloat;
#endif

Burada __LP64__, mevcut mimarinin * 64 bit olup olmadığını gösterir.

32 bit sistemlerin hala 64 bit kullanabileceğini unutmayın, doublesadece daha fazla işlemci süresi gerektirir, bu nedenle CoreGraphics bunu uyumluluk için değil, optimizasyon amacıyla yapar. Performans konusunda endişe duymuyorsanız ancak doğruluk konusunda endişeleriniz varsa kullanın double.

hızlı

Swift yılında CGFloatbir olan structsarıcı etrafında ya Float32 bit mimarileri üzerinde veya Double64 bit olanlar (Sen ile çalıştırıcı veya derleme sırasında bu algılayabilir CGFloat.NativeType)

CoreGraphics kaynak kodu itibaren, içindeCGFloat.swift.gyb :

public struct CGFloat {
#if arch(i386) || arch(arm)
  /// The native type used to store the CGFloat, which is Float on
  /// 32-bit architectures and Double on 64-bit architectures.
  public typealias NativeType = 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.
  public typealias NativeType = Double
#endif

* Özellikle, longs ve işaretçiler, dolayısıyla LP. Ayrıca bkz: http://www.unix.org/version2/whatsnew/lp64_wp.html


1

sadece şunu belirtin - Oca, 2020 Xcode 11.3 / iOS13

Hızlı 5

CoreGraphics kaynak kodundan

public struct CGFloat {
    /// 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.