Skip to content
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

June 2024: Performance and API updates #36

Merged
merged 7 commits into from
Jun 13, 2024
Merged

Conversation

kamranayub
Copy link
Owner

@kamranayub kamranayub commented Jun 13, 2024

BREAKING CHANGES

  • Fix: Mark ExternalGame.Media enum property as nullable
  • Removed public static IdentityConverter.IsAssignableToGenericType helper and replaced with IsIdentityOrValue and IsIdentitiesOrValues static helpers

Changes

  • Performance: Refactored IdentityConverter to speed up deserialization using a compiled Lamda activator and avoiding excessive type checks
  • Expose IdentityConverter.GetIdentitiesActivator for constructing IdentitiesOrValues<> with long[]
  • Expose IdentityConverter.GetValuesActivator for constructing IdentitiesOrValues<> with object[]
  • Expose IdentityConverter.GetIdentityActivator for constructing IdentityOrValue<> with long
  • Expose IdentityConverter.GetValueActivator for constructing IdentityOrValue<> with object

Notes

When dealing with IGDB Data Dumps and using CsvHelper, I needed to create a type converter to construct IdentityOrValue<> and IdentitiesOrValues<> instances. With 280,000 games (and associated data!), that's a lot of instances. In my CPU profile, Activator.CreateInstance was a bottleneck so I went exploring and found Lambda activation instead.

Now in CsvHelper, I have defined a ITypeConverter like this:

public class IgdbIdentityArrayConverter : ITypeConverter
{
    public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        var objectType = memberMapData.Member.MemberType();

        if (!IdentityConverter.IsIdentitiesOrValues(objectType))
        {
            return null;
        }

        var identitiesActivator = IdentityConverter.GetIdentitiesActivator(objectType);

        if (string.IsNullOrEmpty(text))
        {
            return identitiesActivator(new long[0]);
        }

        var values = text.Trim('{', '}').Split(',');

        var convertedValues = values.Select(v => long.Parse(v)).ToArray();

        return identitiesActivator(convertedValues);
    }

    public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        throw new NotImplementedException("Converting IdentitiesOrValues to string is not implemented");
    }
}

public class IgdbIdentityConverter : ITypeConverter
{
    public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        var objectType = memberMapData.Member.MemberType();

        if (!IdentityConverter.IsIdentityOrValue(objectType))
        {
            return null;
        }

        if (long.TryParse(text, out long id))
        {
            var createId = IdentityConverter.GetIdentityActivator(objectType);
            return createId(id);
        }

        return null;
    }

    public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        throw new NotImplementedException("Converting IdentityOrValue to string is not implemented");
    }
}

And that speeds up CSV parsing significantly.

@kamranayub kamranayub changed the title fix(external_games)!: media is nullable June 2024: Performance and API updates Jun 13, 2024
@kamranayub kamranayub added enhancement New feature or request bug Something isn't working labels Jun 13, 2024
@kamranayub kamranayub merged commit a3d42b8 into master Jun 13, 2024
1 check passed
@kamranayub kamranayub deleted the jun-2024/api-fixes branch June 13, 2024 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant