-
Notifications
You must be signed in to change notification settings - Fork 728
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow compilation speed when migrating from 0.x to 1.12.2 #3388
Comments
Hi @m1entus. Thanks for providing so much info with this report. We have never heard of this from anyone else before, and it really doesn't make sense to me why it would be taking so long. These aren't very large generated files, and they don't seem to be very complex either. I'm at a complete loss as to why this is happening. I'm wondering if there is something else going on with either your project or your machine that is causing this. Have you tried having someone else try to compile the project on a different machine? |
Yes it is the same, i just found out that new generator - generates fragments in different manner than before coausing that some of my fragments have generated 22k lines in one file and not 3k lines for specific fragment, for exmple in API in v.0x i have: public struct MessageWithThreadBookmarkDetails: GraphQLFragment {
/// The raw GraphQL definition of this fragment.
public static let fragmentDefinition: String =
"""
fragment MessageWithThreadBookmarkDetails on Message {
__typename
...MessageDetails
bookmark {
__typename
...ThreadBookmarkDetails
}
}
"""
public static let possibleTypes: [String] = ["Message"]
public static var selections: [GraphQLSelection] {
return [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLFragmentSpread(MessageDetails.self),
GraphQLField("bookmark", type: .object(Bookmark.selections)),
]
}
public private(set) var resultMap: ResultMap
public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}
public var __typename: String {
get {
return resultMap["__typename"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "__typename")
}
}
/// set only if the message is being followed or the user is an active participant in the thread, only for home threads
public var bookmark: Bookmark? {
get {
return (resultMap["bookmark"] as? ResultMap).flatMap { Bookmark(unsafeResultMap: $0) }
}
set {
resultMap.updateValue(newValue?.resultMap, forKey: "bookmark")
}
}
public var fragments: Fragments {
get {
return Fragments(unsafeResultMap: resultMap)
}
set {
resultMap += newValue.resultMap
}
}
public struct Fragments {
public private(set) var resultMap: ResultMap
public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}
public var messageDetails: MessageDetails {
get {
return MessageDetails(unsafeResultMap: resultMap)
}
set {
resultMap += newValue.resultMap
}
}
}
public struct Bookmark: GraphQLSelectionSet {
public static let possibleTypes: [String] = ["ThreadBookmark"]
public static var selections: [GraphQLSelection] {
return [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLFragmentSpread(ThreadBookmarkDetails.self),
]
}
public private(set) var resultMap: ResultMap
public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}
public init(roomId: GraphQLID, threadId: String, lastSentMessageId: String, lastViewedMessageId: String? = nil, hasNewMessages: Bool) {
self.init(unsafeResultMap: ["__typename": "ThreadBookmark", "roomId": roomId, "threadId": threadId, "lastSentMessageId": lastSentMessageId, "lastViewedMessageId": lastViewedMessageId, "hasNewMessages": hasNewMessages])
}
public var __typename: String {
get {
return resultMap["__typename"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "__typename")
}
}
public var fragments: Fragments {
get {
return Fragments(unsafeResultMap: resultMap)
}
set {
resultMap += newValue.resultMap
}
}
public struct Fragments {
public private(set) var resultMap: ResultMap
public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}
public var threadBookmarkDetails: ThreadBookmarkDetails {
get {
return ThreadBookmarkDetails(unsafeResultMap: resultMap)
}
set {
resultMap += newValue.resultMap
}
}
}
}
} where fragment is defined this way:
but new generator tool gives me this: public struct MessageWithThreadBookmarkDetails: MyLongCompileTimeLibrary.SelectionSet, Fragment {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.Message }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("bookmark", Bookmark?.self),
.fragment(MessageDetails.self),
] }
/// set only if the message is being followed or the user is an active participant in the thread, only for home threads
public var bookmark: Bookmark? { __data["bookmark"] }
/// used by clients to embed custom metadata in the message, unused by backend
public var metadata: String? { __data["metadata"] }
/// ID (snowflake) of the message, https://github.com/sony/sonyflake
public var id: String { __data["id"] }
/// client provided ID for the message, unused by backend
public var clientId: String? { __data["clientId"] }
/// link previews attached message
public var linkPreviews: [LinkPreview] { __data["linkPreviews"] }
/// ID of the home this message belongs to
public var homeId: MyLongCompileTimeLibrary.ID? { __data["homeId"] }
/// ID of the room this message belongs to
public var channelId: MyLongCompileTimeLibrary.ID { __data["channelId"] }
/// ID of the parent message, only set for replies/comments
public var threadId: String? { __data["threadId"] }
/// profile preview of the message creator
public var profilePreview: ProfilePreview { __data["profilePreview"] }
/// markup text version of the message content
/// "foo @ <@jdoe-user-id> <@here> <@room> & bar - foo"
@available(*, deprecated, message: "Not used")
public var text: String? { __data["text"] }
/// title of the message, only for posts in a forum room
public var title: String? { __data["title"] }
/// plain text version of the message content, used for notifications and message previews
@available(*, deprecated, message: "Not used")
public var plaintext: String? { __data["plaintext"] }
/// content blocks attached message
public var contentBlocks: [ContentBlock]? { __data["contentBlocks"] }
/// if embedding an event, or a meetup was assigned to this message, includes the embedded event/meetup
public var event: Event? { __data["event"] }
/// if embedding a poll includes the embedded poll
public var poll: Poll? { __data["poll"] }
/// if embedding files, includes the embedded files
public var files: [File]? { __data["files"] }
/// if set then the message is an audio message, points to the file (in files) that represents the audio message
public var audioMessageFileId: MyLongCompileTimeLibrary.ID? { __data["audioMessageFileId"] }
/// if embedding giphys, includes the embedded giphys
public var giphys: [Giphy]? { __data["giphys"] }
/// list of mentions in the message, i.e. user or room
public var mentions: Mentions? { __data["mentions"] }
/// if edited includes information on who edited the message
public var edited: Edited? { __data["edited"] }
/// if pinned includes information on who pinned the message
public var pinned: Pinned? { __data["pinned"] }
/// DateTime (RFC3339) when the message was created
public var createdAt: String { __data["createdAt"] }
/// DateTime (RFC3339) when the message was updated
public var updatedAt: String { __data["updatedAt"] }
/// if deleted includes information on who deleted the message
public var deleted: Deleted? { __data["deleted"] }
/// the action that triggered the last update
public var updateActionType: GraphQLEnum<MyLongCompileTimeLibrary.MessageUpdateActionType> { __data["updateActionType"] }
/// number of replies/comments to this message
public var replyCount: Int { __data["replyCount"] }
/// list of profile IDs for users that replied to/commented on the message/post
public var replyProfileIds: [MyLongCompileTimeLibrary.ID] { __data["replyProfileIds"] }
/// list of reactions and associated counts
public var reactionCounts: [ReactionCount] { __data["reactionCounts"] }
/// true if an automated message created by Geneva
public var isPlatformMessage: Bool { __data["isPlatformMessage"] }
/// list of URLs to suppress link previews for
public var linkUrlsToHide: [String]? { __data["linkUrlsToHide"] }
/// permalink for the message, points to the webapp
public var permalink: String { __data["permalink"] }
/// if the message has suggested actions detected within the text, will include metadata about the action
/// that can be taken.
public var suggestedActions: [SuggestedAction]? { __data["suggestedActions"] }
/// the message that this message is a quick reply to
public var inlineMessage: InlineMessage? { __data["inlineMessage"] }
public var activityStatus: [ActivityStatus]? { __data["activityStatus"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var messageDetails: MessageDetails { _toFragment() }
}
/// Bookmark
///
/// Parent Type: `ThreadBookmark`
public struct Bookmark: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.ThreadBookmark }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.fragment(ThreadBookmarkDetails.self),
] }
/// ID of the room
public var roomId: MyLongCompileTimeLibrary.ID { __data["roomId"] }
/// ID of the thread, parent message ID
public var threadId: MyLongCompileTimeLibrary.Snowflake { __data["threadId"] }
/// ID of the last message in the thread
public var lastSentMessageId: MyLongCompileTimeLibrary.Snowflake { __data["lastSentMessageId"] }
/// ID of the last thread message viewed by the user, set by calling updateThreadBookmark
public var lastViewedMessageId: MyLongCompileTimeLibrary.Snowflake? { __data["lastViewedMessageId"] }
/// true if there are unread messages in the thread
public var hasNewMessages: Bool { __data["hasNewMessages"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var threadBookmarkDetails: ThreadBookmarkDetails { _toFragment() }
}
}
/// LinkPreview
///
/// Parent Type: `LinkPreview`
public struct LinkPreview: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.LinkPreview }
/// display title of the link, og:title
public var title: String { __data["title"] }
/// description of the link, og:description
public var description: String? { __data["description"] }
/// url of the link
public var url: String { __data["url"] }
/// type of link, most common types are: image, video, rich.
public var linkType: String { __data["linkType"] }
/// name of the provider/host of the link, ie ???
public var providerName: String? { __data["providerName"] }
/// url of the home page for the link provider/host
public var providerUrl: String? { __data["providerUrl"] }
/// link preview image thumbnail
public var thumbnail: Thumbnail? { __data["thumbnail"] }
/// link preview image
public var image: Image? { __data["image"] }
/// link preview interactive embed html
public var media: Media? { __data["media"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var linkPreviewDetails: LinkPreviewDetails { _toFragment() }
}
/// LinkPreview.Thumbnail
///
/// Parent Type: `LinkPreviewImage`
public struct Thumbnail: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.LinkPreviewImage }
/// URL of the link preview image
public var url: String { __data["url"] }
/// height of the image in pixels
public var height: Int { __data["height"] }
/// width of the image in pixels
public var width: Int { __data["width"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var linkPreviewImageDetails: LinkPreviewImageDetails { _toFragment() }
}
}
/// LinkPreview.Image
///
/// Parent Type: `LinkPreviewImage`
public struct Image: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.LinkPreviewImage }
/// URL of the link preview image
public var url: String { __data["url"] }
/// height of the image in pixels
public var height: Int { __data["height"] }
/// width of the image in pixels
public var width: Int { __data["width"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var linkPreviewImageDetails: LinkPreviewImageDetails { _toFragment() }
}
}
/// LinkPreview.Media
///
/// Parent Type: `LinkPreviewHtml`
public struct Media: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.LinkPreviewHtml }
/// raw html
public var html: String { __data["html"] }
/// height of the interactive embed
public var height: Int? { __data["height"] }
/// width of the interactive embed
public var width: Int? { __data["width"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var linkPreviewHtmlDetails: LinkPreviewHtmlDetails { _toFragment() }
}
}
}
/// ProfilePreview
///
/// Parent Type: `ProfilePreview`
public struct ProfilePreview: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.ProfilePreview }
public var id: MyLongCompileTimeLibrary.ID { __data["id"] }
/// the user's first name
public var firstName: String { __data["firstName"] }
/// the user's last name
public var lastName: String? { __data["lastName"] }
/// globally unique username
public var username: String { __data["username"] }
/// location of the user as a string populated when their location is public
public var location: String? { __data["location"] }
/// the user's default profile color, used when there is no profile picture
public var defaultColor: String { __data["defaultColor"] }
/// the user's profile picture
public var picture: Picture? { __data["picture"] }
public var deletedAt: MyLongCompileTimeLibrary.DateTime? { __data["deletedAt"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var profilePreviewDetails: ProfilePreviewDetails { _toFragment() }
}
/// ProfilePreview.Picture
///
/// Parent Type: `File`
public struct Picture: MyLongCompileTimeLibrary.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: ApolloAPI.ParentType { MyLongCompileTimeLibrary.Objects.File }
public var id: MyLongCompileTimeLibrary.ID { __data["id"] }
/// filename of the file, eg example.txt
public var filename: String { __data["filename"] }
/// mimetype of the file, eg image/png
public var mimetype: String { __data["mimetype"] }
/// s3 bucket the file is stored in
public var s3Bucket: String { __data["s3Bucket"] }
/// s3 key of the file in storage
public var s3Key: String { __data["s3Key"] }
/// size of the file in bytes
public var size: Int { __data["size"] }
/// image metadata, only for image files
public var imageInfo: ImageInfo? { __data["imageInfo"] }
/// video metadata, only for video files
public var videoInfo: VideoInfo? { __data["videoInfo"] }
/// audio metadata, only for audio files
public var audioInfo: AudioInfo? { __data["audioInfo"] }
public struct Fragments: FragmentContainer {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public var fileDetails: FileDetails { _toFragment() }
}
... Looks like that it reattach all embeded properties instead of keeping it in shared place, and idea how this might work in better way in 1.x and use same as previously inheritance from parent ? We have many models where we are adding some properties to base model. And comparing numer of lines generated previously in single file (it is around 65k in total), where new generator gives many files with aournd 22k files per file which is crazy. I love the idea of splitting to different files but wondering how i can solve my problem |
We are currently working on #2560 to allow you to disable fragment field merging into operation models. Once that is done, you'll be able to make your generated files a lot smaller. But even with those large files, the compilation times you're seeing feel way higher than I'd anticipate. Maybe that will solve it, but I'm wondering if there is something else going on here as well. |
@AnthonyMDev If you want i can share with you sample app with some part of fragments generated code, preety lightweight but still it compile a large amount of time, around ~5-10 minutes lol |
@m1entus, there is a preview release for a new feature that should reduce the size of the generated code. See my comment here for more info. Would you be able to try using the preview release for me and let us know if that resolves your compilation time issues as well? Thanks! |
@AnthonyMDev yooo, i just tested and i think it works! (testing on old branch, but seems files are compiling in 8s, so much better than 10 minutes xd) |
Great to hear! We''ll be releasing that to a public release this week! |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better. |
Question
Hey guys,
I am currently migrating to 1.12.2 from 0.x, previously we were genarating only one file with all generation models. Now i am trying to migrate and compile project but compilation times for some files are sooo slow. I am using this kind of configuration:
In addition to that i wanted to check why i have so long compilations speed by checking function compiler times but unfortenately it does not show anything (no warning at all):
As a example i can show some of files from both batch (one that compile super fast, and second one that very slow):
Do you have idea why this is happening or how i can debug it, why compile speed are soooo long ? (i am using m1 max, so normally took few seconds for all generated files - at least before migration).
Initially i also thoutght that this is because of definitions with a lot of parameters in array for fragments, but also doesn't help turning it off.
Thanks for help.
The text was updated successfully, but these errors were encountered: