Какая разница между использованием CGFloat и float?

Я обычно использую CGFloat повсюду, но мне интересно, не получаю ли я бессмысленный "удар производительности" с этим. CGFloat кажется чем-то "тяжелее", чем плавать, не так ли? В каких точках я должен использовать CGFloat, и что действительно имеет значение?

Ответ 1

Как сказал @weichsel, CGFloat - это всего лишь typedef для float или double. Вы можете сами убедиться в Command-двойном щелчке по "CGFloat" в Xcode - он перейдет к заголовку CGBase.h, где определен typedef. Тот же подход используется также для NSInteger и NSUInteger.

Эти типы были введены для упрощения написания кода, который работает как с 32-разрядной, так и с 64-разрядной версией без изменений. Однако, если вам нужна точность float внутри вашего собственного кода, вы можете использовать float, если хотите - это немного уменьшит объем памяти. То же самое относится к целым значениям.

Я предлагаю вам потратить скромное время на то, чтобы сделать ваше приложение 64-битным чистым и попробовать запустить его как таковое, так как большинство компьютеров Mac теперь имеют 64-битные процессоры, а Snow Leopard - полностью 64-разрядные, включая ядро ​​и пользовательские приложения, Apple 64-разрядное Руководство по переходу для Cocoa - полезный ресурс.

Ответ 2

CGFloat является регулярным поплавком на 32-битных системах и двойной в 64-битных системах

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

Таким образом, вы не получите никакого штрафа за производительность.

Ответ 3

Как говорили другие, CGFloat - это поплавок на 32-битных системах и двойной в 64-битных системах. Однако решение сделать это было унаследовано от OS X, где оно было сделано на основе характеристик производительности ранних процессоров PowerPC. Другими словами, вы не должны думать, что float предназначен для 32-разрядных процессоров, а double - для 64-разрядных процессоров. (Я считаю, что процессоры Apple ARM смогли обработать удвоение задолго до того, как они перешли на 64-разрядную версию.) Основной удар по использованию удвоений заключается в том, что они используют в два раза больше памяти и, следовательно, могут быть медленнее, если вы выполняете много операций с плавающей запятой.

Ответ 4

Objective-C

Из исходного кода Foundation в CoreGraphics '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.

Swift

В Swift 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

* В частности, long и указатели, следовательно, LP. См. Также: http://www.unix.org/version2/whatsnew/lp64_wp.html