Why should I use eosio::string over std::string? What are the use cases where it would make a difference?
1 Answer
According to the release notes:
A new type to act as a more efficient replacement to std::string has been added (#459). eosio::string should be more efficient in memory usage and help to reduce the bloat to smart contract WASMs that std::string imposes.
Where PR 459 references the following string bloat problem:
Given a minimal smart contract (con.cpp) with a no-op action:
#include <eosio/eosio.hpp> class [[eosio::contract]] con : public eosio::contract { public: using contract::contract; [[eosio::action]] void act() { } }; EOSIO_DISPATCH(con, (act))
The size of the said contract comes out out to be:
~/con $ ll total 1 -rwxrwxr-x 1 i i 743 2019-03-06 13:37 a.out -rw-rw-r-- 1 i i 202 2019-03-06 13:37 con.cpp
Given a minimal smart contract whilst introducing a std::string:
#include <eosio/eosio.hpp> class [[eosio::contract]] con : public eosio::contract { public: using contract::contract; [[eosio::action]] void act(const std::string& s) { } }; EOSIO_DISPATCH(con, (act))
The size of the contract is now:
~/con $ ll total 4 -rwxrwxr-x 1 i i 3531 2019-03-06 13:46 a.out -rw-rw-r-- 1 i i 222 2019-03-06 13:46 con.cpp
As is shown, this comes out to an extra 2788 bytes of code-bloat.
This poses to be a problem if a developer were to have many trivial/small smart contracts which utilize a std::string. But if the smart contract is already larger in nature, then this effect is minimal.
Therefore a new string type shall be developed for size optimization. This new string class will implement the small string optimization and provide the normal interface that is provided by std::string but at a fraction of the memory footprint.