One- and two-pass assemblers may look the same at the level you describe, but the details are not the same. The symbol table in a two-pass assembler is just a list of names and values. Pass 2 does reparse but it also handles all references the same way. Runtime memory usage depends on the number of symbols in your program.
The symbol table in a one-pass assembler has to store forward references, and you have to write the algorithm to resolve them when the symbols are defined. Is that worth the benefit of only parsing the source once? Different real-world assemblers answer that differently. Also runtime memory usage depends on the number of symbols and the number of forward references in your program.
You can improve one-pass assemblers with some tricks. On many mainframes and some minicomputers, all instructions are the same size. If all instructions can hold an address and the memory can hold the entire program being assembled, a one-pass assembler can store the forward references in linked lists inside the program itself. Or the assembler can write out the binary without fixing the forward references and let the loader fix them.
One major reason for one-pass assemblers is slow I/O devices. If they're magnetic tape drives the computer has to rewind the tape between passes. If they're punched paper tape readers or punch card readers a human has to rewind the tape or reload the cards. Elliminating a pass saved significant time.
One major reason for two-pass assemblers is a sophisticated input language, especially with macros. IBM mainframes heavily used macros. They could take arguments, and could expand to specialized instruction sequences depending on the arguments. So you had to expand all the macros and assemble all the code to find the size of the output, so it was easiest to use two passes.
Some example assemblers:
(1957) SOAP II for the IBM 650 automatically changed the memory layout of the output program to speed up execution. That was possible because of the 650's instruction format, and important because of the 650's magnetic drum memory which had variable access times.
(1960) LGPSAP for the General Precision LGP-30 was a straightforward two-pass assembler, assembling directly into memory but also typing a listing. I'm not sure if you could punch a binary paper tape. Someone created a faster and more powerful one-pass assembler called SCOOP. SCOOP also assembled directly into memory and reused the LGPSAP symbol-table format. In fact the SCOOP code seems to be a patch to LGPSAP! The LGP-30 (from 1956) was not a powerful computer, but you could sit at it, type commands, and get an immediate response -- rare in the 1950s and 1960s.
(1961) SCAT for the IBM 709 had macros and used a compressed format to store assembled programs. You could update an already-assembled program with new assembly-language cards.
(1962) FAP for the IBM 709 and 7090 also had macros, unrelated to SCAT.
(1962) MACRO for the DEC PDP-1 put all the opcodes in the symbol table, so the "instruction" input really just added symbol values, or you could use other arithmetic operations. It used short symbol names and a compressed format for macro definitions, so that it could assemble itself on a computer with 4096 18-bit words of memory.
(1974) FAIL for the DEC PDP-10 had macros and many other fancy features, yet used one pass for speed. Arguments in favor of one pass (on page 12) look quite similar to yours. FAIL left all the forward references, including complicated arithmetic expressions, to the loader.