CGFloatとfloatの違いは何ですか?


169

あちこちでCGFloatを使用する傾向がありますが、これで意味のない「パフォーマンスヒット」が発生するのではないかと思います。CGFloatはfloatよりも「重い」ようですよね?どの時点でCGFloatを使用する必要がありますか、そして実際に何が違いますか?

回答:


193

@weichselが述べたように、CGFloatはどちらかのtypedefにすぎません floatdouble。Xcodeの「CGFloat」をCommand-ダブルクリックすると、自分で確認できます。typedefが定義されているCGBase.hヘッダーにジャンプします。同じアプローチがNSIntegerとNSUIntegerにも使用されます。

これらの型は、変更なしで32ビットと64ビットの両方で機能するコードを簡単に記述できるようにするために導入されました。ただし、必要なのがfloat自分のコード内の精度て使用floatできます。これにより、メモリフットプリントが多少削減されます。整数値についても同様です。

ほとんどのMacには64ビットCPUが搭載されており、Snow Leopardはカーネルとユーザーアプリケーションを含めて完全に64ビットであるため、アプリを64ビットクリーンにするために必要な適度な時間を費やして、そのように実行することをお勧めします。AppleのCocoa 64ビット移行ガイドは、便利なリソースです。


もうわかったと思います。しかし、iPhoneではそれほど問題ではないようです。

4
私たちが知っているiPhoneでは、違います。しかし、それは賢明な将来性のコードに常にだし、これは、簡単に安全にOS X用の同じコードを再利用することになるだろう
クインテイラー

つまり、基本的に、プロセッサアーキテクチャに縛られることになるので、floatまたはdoubleを直接使用しないでください(そして、私はこの数年前に高速JVMが解決されたと思いました:))。では、どのプリミティブが安全ですか?int
Dan Rosenstark、2010

9
プリミティブを直接使用しないでください。64ビットなどのオーバーフローする可能性のあるデータを格納するために変数が使用される可能性がある場合など、ストレートプリミティブが問題になる場合があります。一般的に、コードが別のアーキテクチャで爆発する可能性が低いという点で、アーキテクチャに依存するtypedefを使用する方が安全です。ただし、32ビットタイプを使用すると完全に安全になり、メモリを節約できる場合があります。プリミティブのサイズは、JVMの問題よりは小さいかもしれませんが、Obj-CとCはコンパイルされており、32ビットと64ビットのライブラリーとコードを混在させることは確かに問題があります。
Quinn Taylor、

1
@QuinnTaylorは、CGFloatがオーバーフローしないのに、floatがオーバーフローする実際的な例を提供できますか?floatとCGFloatはどちらもビット数が有限です。保持できるよりも多くのビットを格納する必要があるため、両方をオーバーフローさせることができます。
Pwner

76

CGFloatは、32ビットシステムでは通常の浮動小数点であり、64ビットシステムではdoubleです。

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

したがって、パフォーマンスが低下することはありません。


3
まあ、あなたがメモリを心配している場合は、2倍のメモリを使用します。
タイラー

8
ただし、64ビットのみ。
クインテイラー

13
正解です。iPhoneOSは32ビットです。あなたがそれについて考えるならば、iPhoneは32ビットの4GB RAM制限を推進しておらず、Intelプロセッサ(64ビットは32ビットより速い)を使用していません。さらに、モダンランタイムを使用しており(デスクトップ上の32ビットのレガシーランタイムとは対照的です。興味がある場合は、これらの用語についてはSOを使います)、基本的に64ビットOS Xで可能なすべてのことを実行できます。たぶん、いつかiPhone OSを実行し、64ビットのデバイスが見つかるでしょうが、現在はありません。
クインテイラー

23
入力:iPhone 5S
dgund

7
5Sは64ビットになり、前回カンファレンス(ロンドン)に参加したとき、彼らはios7で32ビットアプリを実行する方法は、メモリ内の別の共有キャッシュプールを初期化することであり、全体としてより多くのメモリを使用する可能性があると述べました。ですから、64ビットまですべてを変換する価値があります。(5.1以上または6.0以上を引き続きサポートする場合を除く)
phil88530 2013

2

他の人が言ったように、CGFloatは32ビットシステムではfloat、64ビットシステムではdoubleです。ただし、その決定は、初期のPowerPC CPUのパフォーマンス特性に基づいて行われたOS Xから継承されました。つまり、floatが32ビットCPU用であり、doubleが64ビットCPU用であるとは考えないでください。(私は、AppleのARMプロセッサは64ビットになるよりずっと前にdoubleを処理できたと思います。)doubleを使用する主なパフォーマンスヒットは、2倍のメモリを使用するため、多くの浮動小数点演算を行うと遅くなる可能性があります。 。


2

Objective-C

CoreGraphics 'のFoundationソースコードから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

Copyright(c)2000-2011 Apple Inc.

これは本質的にやっています:

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

どこ __LP64__現在のアーキテクチャ*が64ビットであるかどうかを示します。

32ビットシステムでも64ビットを使用できることに注意してください。doubleプロセッサ時間が長くなるだけなので、CoreGraphicsは互換性のためではなく、最適化のためにこれを行います。パフォーマンスは気にしなくても、精度は気になる場合は、を使用してくださいdouble

迅速

スウィフトでは、CGFloatあるstructいずれかのラッパーFloat、32ビットアーキテクチャ上またはDouble(あなたがしてランやコンパイル時にこれを検出することができ、64ビットのものにCGFloat.NativeType

CoreGraphicsソースコードから、CGFloat.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

*具体的には、longsとポインタ、したがってLP。参照:http : //www.unix.org/version2/whatsnew/lp64_wp.html


1

それだけ言ってください-2020年1月Xcode 11.3 / iOS13

スウィフト5

CoreGraphicsソースコードから

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.