Kaffeine/telegram-qt

Optimize memory allocation on Telegram API calls

Kaffeine opened this issue · 0 comments

Generated Telegram API methods implementation can reserve the exact amount of memory in the output byte array.

The generated code should be readable, so:

  • The size calculation code line length should be limited to 120 symbols
  • It's OK for Strings and ByteArrays to treat length bytes as 4 (better than use ternary operators)
  • The addendums (except Strings and ByteArrays) should have inline comments (TLValue constant name for functions, argument/member name in all other cases; size bytes should be decorated as "4 /* size bytes */")

Commits:

  • Introduce sizeInBytes() const methods for all TLTypes
  • Introduce output.reserve() generation for all methods

Bonus:

  • Make sizeInBytes() constexpr if possible:
    • The type has only one tlType value
    • The type has no complex or Strings/ByteArrays members
    • E.g.: TLContact, TLContactSuggested, TLContactLink, TLContactBlocked, etc...

Expected diff would look like:

quint64 CTelegramConnection::accountCheckUsername(const QString &username)
{
    QByteArray output;
+   output.reserve(4 /* AccountCheckUsername */
+                  + username.size() + 4 /* size bytes */);
    CTelegramStream outputStream(&output, /* write */ true);
    outputStream << TLValue::AccountCheckUsername;
    outputStream << username;
    return sendEncryptedPackage(output);
}
...

quint64 CTelegramConnection::accountReportPeer(const TLInputPeer &peer,
                                               const TLReportReason &reason)
{
    QByteArray output;
+   output.reserve(4 /* AccountReportPeer */ + peer.sizeInBytes() + reason.sizeInBytes());
    CTelegramStream outputStream(&output, /* write */ true);
    outputStream << TLValue::AccountReportPeer;
    outputStream << peer;
    outputStream << reason;
    return sendEncryptedPackage(output);
}

quint64 CTelegramConnection::accountResetAuthorization(quint64 hash)
{
    QByteArray output;
+   output.reserve(4 /* AccountResetAuthorization */ + 8 /* hash */);
    CTelegramStream outputStream(&output, /* write */ true);
    outputStream << TLValue::AccountResetAuthorization;
    outputStream << hash;
    return sendEncryptedPackage(output);
}
quint64 CTelegramConnection::authBindTempAuthKey(quint64 permAuthKeyId, quint64 nonce,
                                                 quint32 expiresAt,
                                                 const QByteArray &encryptedMessage)
{
    QByteArray output;
+   output.reserve(4 /* AuthBindTempAuthKey */ + 8 /* permAuthKeyId */ + 8 /* nonce */
+                  + 4 /* expiresAt */
+                  + encryptedMessage.size() + 4 /* size bytes */);
    CTelegramStream outputStream(&output, /* write */ true);
    outputStream << TLValue::AuthBindTempAuthKey;
    outputStream << permAuthKeyId;
    outputStream << nonce;
    outputStream << expiresAt;
    outputStream << encryptedMessage;
    return sendEncryptedPackage(output);
}