0% found this document useful (0 votes)
71 views

(Ebook) TypeScript High Performance by Ajinkya Kher ISBN 9781785288647, 1785288644 All Chapters Instant Download

The document provides information about the ebook 'TypeScript High Performance' by Ajinkya Kher, which focuses on efficient strategies for handling asynchrony and optimizing resource delivery in TypeScript. It includes details on various related ebooks available for download, as well as acknowledgments and insights from the author and reviewers regarding the importance of performance in software development. The book is designed to help both novice and experienced developers improve their coding efficiency and resource management.

Uploaded by

kapparmiong45
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views

(Ebook) TypeScript High Performance by Ajinkya Kher ISBN 9781785288647, 1785288644 All Chapters Instant Download

The document provides information about the ebook 'TypeScript High Performance' by Ajinkya Kher, which focuses on efficient strategies for handling asynchrony and optimizing resource delivery in TypeScript. It includes details on various related ebooks available for download, as well as acknowledgments and insights from the author and reviewers regarding the importance of performance in software development. The book is designed to help both novice and experienced developers improve their coding efficiency and resource management.

Uploaded by

kapparmiong45
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 76

Visit https://ebooknice.

com to download the full version and


explore more ebooks

(Ebook) TypeScript High Performance by Ajinkya Kher


ISBN 9781785288647, 1785288644

_____ Click the link below to download _____


https://ebooknice.com/product/typescript-high-
performance-23379932

Explore and download more ebooks at ebooknice.com


Here are some recommended products that might interest you.
You can download now and explore!

(Ebook) Biota Grow 2C gather 2C cook by Loucas, Jason; Viles, James


ISBN 9781459699816, 9781743365571, 9781925268492, 1459699815,
1743365578, 1925268497

https://ebooknice.com/product/biota-grow-2c-gather-2c-cook-6661374

ebooknice.com

(Ebook) TypeScript Handbook - TypeScript 4.7 by typescriptlang.org

https://ebooknice.com/product/typescript-handbook-
typescript-4-7-44980036

ebooknice.com

(Ebook) TypeScript Handbook - TypeScript 4.8 by typescriptlang.org

https://ebooknice.com/product/typescript-handbook-
typescript-4-8-45950316

ebooknice.com

(Ebook) TypeScript Handbook - TypeScript 4.8 by typescriptlang.org

https://ebooknice.com/product/typescript-handbook-
typescript-4-8-46499030

ebooknice.com
(Ebook) Principles of High-Performance Processor Design: For High
Performance Computing, Deep Neural Networks and Data Science by
Junichiro Makino ISBN 9783030768706, 3030768708

https://ebooknice.com/product/principles-of-high-performance-
processor-design-for-high-performance-computing-deep-neural-networks-
and-data-science-34095162
ebooknice.com

(Ebook) High Performance Python by Micha Gorelick, Ian Ozsvald

https://ebooknice.com/product/high-performance-python-42370716

ebooknice.com

(Ebook) Python High Performance by Gabriele Lanaro ISBN 9781787282896,


1787282899

https://ebooknice.com/product/python-high-performance-6781574

ebooknice.com

(Ebook) High Performance Habits by Brendon Burchard ISBN


9781401952853, 1401952852

https://ebooknice.com/product/high-performance-habits-48256236

ebooknice.com

(Ebook) Julia High Performance by Avik Sengupta ISBN 9781788292306,


1788292308

https://ebooknice.com/product/julia-high-performance-11117298

ebooknice.com
TypeScript High Performance

Learn efficient strategies for handling asynchrony and


optimizing resource delivery

Ajinkya Kher

BIRMINGHAM - MUMBAI
TypeScript High Performance
Copyright © 2017 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or
transmitted in any form or by any means, without the prior written permission of the
publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the
information presented. However, the information contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing, and its
dealers and distributors will be held liable for any damages caused or alleged to be caused
directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the
companies and products mentioned in this book by the appropriate use of capitals.
However, Packt Publishing cannot guarantee the accuracy of this information.

First published: August 2017

Production reference: 1210817


Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

ISBN 978-1-78528-864-7

www.packtpub.com
Credits

Author Copy Editors


Ajinkya Kher Sameen Siddiqui
Pranjali Chury

Reviewer Project Coordinator


Andrew Macrae Vaidehi Sawant

Commissioning Editor Proofreader


Aaron Lazar Safis Editing

Acquisition Editor Indexer


Karan Sadawana Francy Puthiry

Content Development Editor Graphics


Zeeyan Pinheiro Abhinash Sahu

Technical Editor Production Coordinator


Vibhuti Gawde Nilesh Mohite
Foreword
Developing efficient software systems that meet the performance requirements and work
correctly as expected can be challenging without commitment from all layers of the
software development process. Adding more resources or patching things here and there on
an inefficiently written piece of software is often not enough and can greatly impact the
usability and usefulness of the system.

When performance is measured in microseconds, we can no longer rely on the hardware


performance improvements alone and need to optimize every aspect of the system, be it
selecting basic data structures or rendering critical resources. We need to understand and
make design decisions related to time-critical components and resources for improved
response time. Meanwhile, we cannot ignore testing the system for correctness and catching
bugs early on. I am delighted to see Ajinkya brings these perspectives to the readers in his
clearly written and well composed introduction to TypeScript for high efficiency and
performance. You are invited to think in terms of performance optimization and be
cognizant of the computational resources when building software systems. The book
provides clear examples related to efficient programming using TypeScript as well as
managing resources for responsive systems and user interfaces. Not only is the book
written in such a way that the reader can ramp up quickly to more advanced language
constructs, but they can also appreciate the rationale behind various choices for the given
use case. The practical examples meshed with empirical analysis of the performance for
each of the given design and implementation choices are quite refreshing and are scattered
throughout the book. Even novice readers can get the necessary insights and develop the
thought process for writing efficient and responsive software systems.

I am impressed by how much ground Ajinkya has covered in this book. Given his solid
background in full-stack software development, experience working with real-time
systems, and the desire to learn and grow along the way, the polished outcome in the form
of this book is not surprising. Ajinkya has truly brought his knowledge and insights to the
readers in an accessible manner and has let them in on the winning secrets that he has
leveraged in both professional settings and while triumphing in multiple Hackathons.

Maria Riaz, PhD

Software Engineer, Google Inc.


Over the last two decades, JavaScript has grown from enabling developers to perform
simple interactions with in-browser HTML to being the core of enterprise applications, both
frontend and backend. The success has become more apparent with the advent and creation
of NodeJS, Cordova, Ionic, and serverless frameworks, all of whom have adopted and
support TypeScript. This growth, coupled with the always increasing demand for complex
and performant JavaScript, has fueled the need for stricter typing, structures, and code
decoupling.

As a passionate technologist, fueled engineer, and creative problem solver, I have been a
witness and part of this evolution. I started using JavaScript in 2001 and have thoroughly
enjoyed the evolution since then. I enjoy the quirks of the language and the tiny things I’ve
spent hours trying to debug. I used to code in Notepad and would spend the proverbial 8
hours searching for a misspelled variable and massaging the bruises on my forehead from
the wall. I enjoy listening to everyone’s unique story about how they discovered that the
parseInt() function defines and documents two parameters, with the second being the radix
and probably the most frustrating parameter as it does not default to the expected value of
10.

We all have those unique yet similar stories. With TypeScript, we will save our children
from those headaches and hopefully reduce their chronic traumatic encephalopathy from
continuously beating their head against your basement wall. I have dabbled with
technologies on personal projects and I have worked for some of the biggest companies in
the world, including Microsoft, Siemens, Goldman Sachs, Deloitte, AT&T, and Coca-Cola.
With that experience, I hope that some of that can be shared with you as a reader of this
book.

If you are just beginning to venture into JavaScript or TypeScript, or if you’re a seasoned
veteran like me, you have something to gain from these pages. In my years of development
and consulting, I have never seen someone as passionate about learning tooling and
languages as Ajinkya. I worked with him when he first ventured into frontend development
with AngularJS.
The evolving world can be a scary place for most developers. This book has been designed
and is intended to allow you to smoothly transition from JavaScript to TypeScript, which is
why I highly recommend every JavaScript and TypeScript developer reads it cover to cover.
I recommend you read each section with an open mind and ask yourself questions or
consider reaching out to and engaging in forums, the publishing company, or industry
experts.

Congratulations on taking the first step toward the future of JavaScript, and smile while
you read this book!

Brian O’Connor

Solution Principal, Slalom Consulting


About the Author
Ajinkya Kher is a full stack developer, currently working at Microsoft on the
communications infrastructure for Skype and Microsoft teams. He is passionate about
modern scalable architectural patterns, efficient problem solving, and process design. His
experience and expertise is in the .NET middle tier/backend and modern HTML5 frontend
frameworks.

He loves getting his hands dirty with the latest and the greatest technologies out there. In
his free time, you can find him winning Hackathons, building mobile applications, and
lifting weights. He has been playing tennis for more than a decade and has been an ardent
fan of cricket and Sachin Tendulkar since childhood, his weekends are thus often spent
playing these two sports. He also likes to practice and read about spirituality and
philosophy whenever he can.

Check out his latest podcast Building Modern Web Applications using
React/Redux/Angular2/RxJs on YouTube and you can also follow him on LinkedIn.
Acknowlegement
I would like to express my gratitude to several people who have helped me through the
journey of this book. I would like to begin with my friends at Packt Publishing–-Sonali,
Kinnari, Vibhuti, and Zeeyan, who were of great help right from laying out the scope of the
book to offering comments, proofreading, and editing the chapters, all of which, I’m sure,
resulted in enhancing the quality of the book.

I would like to thank Brian and Maria for their generous contributions to this book. Both
Brian and Maria helped proofread the book and offered great feedback and encouragement.
I would like to specifically thank Brian for his invaluable contributions to Chapter 8, Build
and Development Strategies for Large-Scale Projects of this book.

I would like to thank Raji, who has constantly encouraged me to keep going and complete
this book. I would also like to thank my friends at work who encouraged me in the writing
process.

I would like to thank my family–-my mom, my dad, and my sister, Anushka, for their
invaluable and sincere feedback, encouragement, and most importantly, their patience
throughout the process. My parents were on a vacation here in Seattle as I was working
toward the completion of this book. They were very cheerful and supportive despite all the
time it took me away from them. This book wouldn’t have been complete without their
support.

Lastly, I would like to thank everyone who has helped shape me over the years and put me
in a position to share my insights and experience with you all in the form of this book.
About the Reviewer
Andrew Leith Macrae first cut his programming teeth on an Apple IIe, poking bytes into
the RAM. Over the years, he has developed interactive applications with Hypercard,
Director, Flash, and more recently, Adobe AIR for mobile. He has also worked with HTML
since there was HTML to work with and is currently working as a senior frontend
developer at The Learning Channel (www.tsc.ca), using Angular 4 with Typescript.

He is convinced that TypeScript is the future of JavaScript, bringing the structure and
discipline of strongly typed object-oriented language to facilitate efficient, intentional
coding for the development of large-scale applications for the Web.

You can find out more about Andrew or contact him at www.adventmedia.net.
www.PacktPub.com
For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a
print book customer, you are entitled to a discount on the eBook copy. Get in touch with us
at service@packtpub.com for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a
range of free newsletters and receive exclusive discounts and offers on Packt books and
eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt
books and video courses, as well as industry-leading tools to help you plan your personal
development and advance your career.

Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Customer Feedback
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial
process. To help us improve, please leave us an honest review on this book's Amazon page
at https://www.amazon.com/dp/1785288644.

If you'd like to join our team of regular reviewers, you can e-mail us at
customerreviews@packtpub.com. We award our regular reviewers with free eBooks and
videos in exchange for their valuable feedback. Help us be relentless in improving our
products!
I dedicate this book to my mom, who is my first teacher, friend, and mentor. She taught me the
alphabet as a child, and she's still the first one to update me on the latest technological innovations.
She has dedicated her life towards my all-round growth and her contributions to my life are
incalculable.
Table of Contents
Preface 1
Chapter 1: Efficient Implementation of Basic Data Structures and
Algorithms 7
Strings 8
String concatenation 9
String replacement 12
Classes and interfaces 15
Loops and conditions 20
Arrays and sorting 26
Operators 30
Summary 33
Chapter 2: Variable Declarations, Namespaces, and Modules 34
Variable declarations 34
The var declarations 36
The let declarations 39
The const declarations 41
Namespaces and modules 41
Modules 45
Summary 48
Chapter 3: Efficient Usage of Advanced Language Constructs 49
Arrow functions 50
Mixins 55
Declaration merging 59
Triple-slash directives 64
Answers to declaration merging questions 67
Summary 71
Chapter 4: Asynchronous Programming and Responsive UI 72
Fundamentals of asynchronous programming and event loop 74
Synchronous data fetch 75
Asynchronous data fetch 76
Event loop 77
Callbacks 87
Callback Hell 93
Promises 95
Async and await 103
Summary 112
Chapter 5: Writing Quality Code 113
Unit tests 114
Static code analysis with TSLint 129
Setting up TSLint for your project 130
Editing default rules 136
Extending TSLint rules 138
TSLint VSCode Extension 139
Summary 142
Chapter 6: Efficient Resource Loading - Critical Rendering Path 143
Resource delivery across the internet 144
Optimizing the critical rendering path 148
Optimization 1 - render blocking CSS 152
Optimization 2 - render blocking JS 154
Non-blocking UI 157
Massive data downloads 157
Massive data uploads 161
Summary 162
Chapter 7: Profile Deployed JS with Developer Tools and Fiddler 163
Chrome Developer Tools 164
Memory profiling 164
Latency and computation time profiling 169
The Network tab 174
Fiddler 180
Summary 188
Chapter 8: Build and Deployment Strategies for Large-Scale Projects 189
Building locally 190
Grunt 190
Gulp 191
MSBuild 192
Continuous integration (CI) 193
The process 194
Jenkins 196
Bamboo 196
Continuous delivery (CD) 196
Chef 198

[]
Puppet 198
Containerization 198
Docker 199
Serverless applications 199
Testing 199
Summary 200
Index 201

[]
Preface
Over the last two decades, JavaScript has grown from enabling developers to perform
simple interactions with in-browser HTML to being the core of enterprise applications, both
frontend and backend. This success has become more apparent with the advent and
creations of NodeJS, Cordova, Ionic, and serverless frameworks, all of which have adopted
and support TypeScript. This growth, coupled with the ever-increasing demand for
complex and performant JavaScript, has fueled the need for stricter typing, structures, and
code decoupling.

TypeScript, created by Microsoft, is the long-awaited solution to these needed language


constructs. It is a superset of JavaScript, allowing for compilation to JavaScript and for
JavaScript to run within TypeScript. TypeScript is both open source and has backing from
major JavaScript libraries and frameworks, namely React, Angular, Express, Knockout, and
Ionic. This backing is evidence alone that TypeScript has garnered support from the cutting
edge in the industry.

With this evolution, it is necessary for learning to take place for newbies and gurus alike.
This book has been designed to walk through various topics of the language, building into
meaningful constructs to help you, as a TypeScript developer, build scalable, efficient, and
maintainable applications from the first line of code. We start by walking you through
language structure and terminology, continue through optimizing your code to load
quickly and fine-tune performance, and wrap up with a discussion on building and
deploying applications for large-scale and enterprise applications.

TypeScript is here to stay and will be looked back upon as the next iteration of JavaScript
just as its predecessors, such as Prototype, jQuery, Dojo, and Mootools, were. This book will
walk you through the language and will explain how to write efficient enterprise
TypeScript to scale.

What this book covers


This book has been assembled in topics that allow you to focus on your topics of interest.
Although we have tried to build self-contained chapters and sections, we highly
recommend reading each chapter thoroughly, as the latter sections in the book build on
material from the initial chapters.
Preface

Part I – Efficient usage of data structures,


language constructs, and handling asynchrony
Chapter 1, Efficient Implementation of Basic Data Structures and Algorithms, covers the efficient
implementation of basic TypeScript data structures, data types, and flow control with the
help of classic algorithms.

Chapter 2, Variable Declarations, Namespaces, and Modules, describes the distinction and
correct usage of variable declarations. It also describes code organization strategies, namely
leveraging namespaces and modules.

Chapter 3, Efficient Usage of Advanced Language Constructs, covers several different language
constructs in TypeScript. It explains how to use them, the scenarios in which to use each
construct, and their efficient usage.

Chapter 4, Asynchronous Programming and Responsive UI, is a deep dive into the world of
asynchronous programming. We walk you through the massive performance hits your
application can take if not built correctly, and we discuss strategies and tips for efficient
coding.

Part II – Performance monitoring, code quality,


and resource optimizations
Chapter 5, Writing Quality Code, covers the several configurations available with TSLint and
how they can be used to improve code quality and performance.

Chapter 6, Efficient Resource Loading - Critical Rendering Path, introduces the critical
rendering path and the steps involved in the process of loading a web application. We
discuss strategies for quick and non-blocking resource loading to produce a highly
responsive and performant application load.

Chapter 7, Profile Deployed JS with Developer Tools and Fiddler, introduces the concept of
profiling and the tools available. We compare the performance results of quality code
written with the help of TSLint and compare it to poorly written TypeScript code.

Part III – Building and deploying strategies for


large-scale TypeScript projects
Chapter 8, Building and Deploying Strategies for Large Scale Projects, covers the build and
deployment process of real-world, enterprise-scale TypeScript applications.

[2]
Preface

What you need for this book


The book requires the following things:

Node and NPM


TypeScript
Mocha Test Framework
Chai Assertion Library
Windows, Linux, or MacOS
Modern browsers--Chrome, Edge, and IE
Telerik Fiddler
Frontend editor--preferably VS Code or Atom/Sublime Text

Who this book is for


The scope of this book is broad, as are the applications and solutions that can be delivered
through TypeScript. As such, this book is essential for those who have a passion for
software at every stage of the life cycle, from ideation to architecture, design, build, and test.
This book should appeal to people who have embraced TypeScript for years and people
who have been in the JavaScript world and have debated making the jump to TypeScript.

Basic knowledge of TypeScript and some experience using JavaScript are prerequisites for
this book.

Conventions
In this book, you will find a number of text styles that distinguish between different kinds
of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions,
pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "Since the
text variable was not previously defined, the log output will now display a compilation
error." A block of code is set as follows:
// const tests
function constTest(): () => number {
const x: number = 16;
x = 4; // Left-hand side of assignment expression cannot be
a constant
return function innerFunction(): number {
x++; // the operand of an increment or decrement operator

[3]
Preface

cannot be a constant
return x;
}
}

console.log('const test: ', constTest()());

When we wish to draw your attention to a particular part of a code block, the relevant lines
or items are set in bold:
[default]
exten => s,1,Dial(Zap/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)

Any command-line input or output is written as follows:


ts-mocha test.ts

New terms and important words are shown in bold. Words that you see on the screen, for
example, in menus or dialog boxes, appear in the text like this: "Let's take a look at the
Network tab of the Developer Tools."

Warnings or important notes appear like this.

Tips and tricks appear like this.

Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this
book-what you liked or disliked. Reader feedback is important for us as it helps us develop
titles that you will really get the most out of. To send us general feedback, simply e-mail
feedback@packtpub.com, and mention the book's title in the subject of your message. If
there is a topic that you have expertise in and you are interested in either writing or
contributing to a book, see our author guide at www.packtpub.com/authors.

[4]
Preface

Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you
to get the most from your purchase.

Downloading the example code


You can download the example code files for this book from your account at
http://www.packtpub.com. If you purchased this book elsewhere, you can visit
http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:

1. Log in or register to our website using your e-mail address and password.
2. Hover the mouse pointer on the SUPPORT tab at the top.
3. Click on Code Downloads & Errata.
4. Enter the name of the book in the Search box.
5. Select the book for which you're looking to download the code files.
6. Choose from the drop-down menu where you purchased this book from.
7. Click on Code Download.

Once the file is downloaded, please make sure that you unzip or extract the folder using the
latest version of:

WinRAR / 7-Zip for Windows


Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub


https://github.com/PacktPublishing/TypeScript-High-Performance. We also have
other code bundles from our rich catalog of books and videos available at
https://github.com/PacktPublishing/. Check them out!

[5]
Preface

Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do
happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-
we would be grateful if you could report this to us. By doing so, you can save other readers
from frustration and help us improve subsequent versions of this book. If you find any
errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting
your book, clicking on the Errata Submission Form link, and entering the details of your
errata. Once your errata are verified, your submission will be accepted and the errata will
be uploaded to our website or added to any list of existing errata under the Errata section of
that title. To view the previously submitted errata, go to
https://www.packtpub.com/books/content/support and enter the name of the book in the
search field. The required information will appear under the Errata section.

Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At
Packt, we take the protection of our copyright and licenses very seriously. If you come
across any illegal copies of our works in any form on the Internet, please provide us with
the location address or website name immediately so that we can pursue a remedy. Please
contact us at copyright@packtpub.com with a link to the suspected pirated material. We
appreciate your help in protecting our authors and our ability to bring you valuable
content.

Questions
If you have a problem with any aspect of this book, you can contact us at
questions@packtpub.com, and we will do our best to address the problem.

[6]
Efficient Implementation of
1
Basic Data Structures and
Algorithms
One of the most important things to achieve optimal performance with any language is to
understand the correct usage of the data types and the constructs it offers. If leveraged
optimally, these features can help in producing a robust and high performance application,
but if leveraged in a non-optimal fashion, the same features can adversely impact the
overall performance and usability of the end product.

Let's take a look at the performance impact with the help of the following basic constructs,
operations, and data structures:

Strings: We will take a look at string concatenation and string replacement. We


will explore different ways of performing the same and understand the relative
merits of the different ways in terms of their performance impact.
Classes and interfaces: We will explore a famous design pattern with the help of
classes and interfaces and understand how a good design can help in achieving a
durable and scalable application.
Loops and conditions: We will look at the relative performances of the different
looping and conditional constructs the language offers.
Arrays and sorting: We will cover arrays by exploring a famous comparison-
based sorting algorithm and understand how the basics of optimizations can
greatly enhance the performance of an application.
Operators: We will take a look at the different operators that the language offers
and their basic usage.
Efficient Implementation of Basic Data Structures and Algorithms

Strings
Let's start by taking a look at strings. In TypeScript, you can create a string in one of the
following ways:
var test1: string = 'test string';

var test2: String = new String('test string');

For all practical purposes, you would almost always use the first way to work with strings.
The only difference between the two is that string is a literal type and a preferred way to
declare strings in TypeScript. String is an object type, which is essentially a wrapper object
around the string. From a performance standpoint, literal types tend to perform better than
object types. We can confirm this by running a simple code snippet as mentioned in the
following code snippet:
function createString_1(): string {
return `Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry''s
standard dummy text ever since the 1500s, when an unknown
printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also
the leap into electronic typesetting, remaining essentially
unchanged.It was popularised in the 1960s with the release of
Letraset sheets containing Lorem Ipsum passages, and more
recently with desktop publishing software like Aldus PageMaker
including versions of Lorem Ipsum.`;
}

function createString_2(): String {


return new String(`Lorem Ipsum is simply dummy text of the
printing and typesetting industry. Lorem Ipsum has been the
industry''s standard dummy text ever since the 1500s, when an
unknown printer took a galley of type and scrambled it to make a
type specimen book. It has survived not only five centuries, but
also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of
Letraset sheets containing Lorem Ipsum passages, and more
recently with desktop publishing software like Aldus PageMaker
including versions of Lorem Ipsum.`);
}

// calculate time taken to create 50, 000 'strings'


let time1: number = Date.now();
for (let i = 0; i < 50000; i++) {
createString_1();
}

[8]
Efficient Implementation of Basic Data Structures and Algorithms

let time2: number = Date.now();


console.log('Time difference (createString_1): ', time2 - time1);

// calculate time taken to create 50, 000 'Strings'


time1 = Date.now();
for (let i = 0; i < 50000; i++) {
createString_2();
}

time2 = Date.now();
console.log('Time difference (createString_2): ', time2 - time1);

The preceding code snippet creates a long string (the famous filler text mostly used as a
placeholder on visual web elements) using the preceding described two ways.

The multiline string is represented in TypeScript by enclosing the string


within two back-tick/back-quote (`) characters. It's that easy!

Now, let's take a look at the results of executing the preceding code snippet:

Chrome (v56) IE (v11) Edge (v38)


createString_1() : string 3 ms 17 ms 13 ms
createString_2(): String 5 ms 42 ms 31 ms

Every set of time-based results mentioned in this book is an average of five


runs. For example, the average runtime of createString_1() on
Chrome (v56) across five runs is 3 milliseconds. We cover the runtime
across three browsers - Google Chrome version 56, Internet Explorer
Version 11, and Microsoft Edge Version 38.

As you can see from the results, the literal type string does behave slightly better. The
creation of the string, however, is not the most impacting operation that would affect your
application. Let's take a look at some classic string manipulation operations.

String concatenation
Let's start with string concatenation. Take a look at the following code snippet:
function createString(): string {
return `Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry''s

[9]
Efficient Implementation of Basic Data Structures and Algorithms

standard dummy text ever since the 1500s, when an unknown


printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also
the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of
Letraset sheets containing Lorem Ipsum passages, and more
recently with desktop publishing software like Aldus PageMaker
including versions of Lorem Ipsum.`;
}

let time1: number = Date.now();


let s1: string = '';

for (let i = 0; i < 40000; i++) {


s1 = s1.concat(createString());
}

let time2: number = Date.now();


console.log('Time difference: ', time2 - time1);

let s2: string = '';


time1 = Date.now();

for (let i = 0; i < 400000; i++) {


s2 += createString();
}

time2 = Date.now();
console.log('Time difference: ', time2 - time1);

The preceding snippet contains a simple function createString, which returns a long
string, precisely 617 characters long. We append this string to itself 40,000 times. In the first
loop, s1 does so by calling s1.concact(createString()) as many times, and in the
second loop, s2 does so by calling s2+= createString() as many times. This is just a
shorthand for s2 = s2 + createString().

When you analyze these loops, how long do you think they took to complete execution?
Did one substantially outperform the other? Or, do you think they're just two different
ways to append a string to itself, and has no impact on performance? Well, here are the
results:

Chrome (v56) IE (v11) Edge (v38)


Loop 1 7 ms 50 ms 36 ms
Loop 2 60 ms 183 ms 163 ms

[ 10 ]
Efficient Implementation of Basic Data Structures and Algorithms

The preceding results are an average of five runs. As you can clearly see, Loop 1
outperforms Loop 2 massively.

Just to understand how massive the impact on the end result would be, consider the
following scenario. Consider a social web application, which when the user starts on his/her
end loads the entire friend/contact list and the entire conversation history with each
contact. Hypothetically, assume that the user has 100 contacts, and with each contact he/she
has 10 conversations. Let's further assume each conversation to be essentially the preceding
string in our example appended to itself 40,000 times. Using our preceding results
(considering Chrome as the web browser), with an inefficient implementation of string
concatenation the page load time would be 100 * 10 * 60 milliseconds = 60,000 milliseconds =
60 seconds or 1 minute. Now, that's a really long time the user has to wait before the
application becomes functional. Such sluggishness can greatly impact the application's
usability and user engagement.

As opposed to this, if the user was to load the same application with the efficient string
concatenation technique, the user wait time would be 100 * 10 * 7 = 7,000 milliseconds = 7
seconds, which is not quite that bad.

If you're starting to appreciate the powers of efficient implementation, we're just getting
started. The time performance isn't even the critical impact factor. The resource that is
greatly impacted is memory!

When you do s1.concact(createString()), you're essentially appending the string on


the same object, as a result of this the total memory consumption is increased only by the
memory needed by the additionally appended string.

However, when you do s2+= createString(), you're essentially creating a new object
each time. If s2 was pointing to a memory block which occupies x bytes, now after one call
to s2+= createString(), it is pointing to a new memory block which occupies x + x =
2x bytes. Thus, at each step, the total memory consumption is greatly increased.

After 40,000 such invocations, the first loop will result in total memory consumption of
40,000 * x bytes, whereas the second loop will result in total memory consumption of x + 2x
+ 3x + ... + 40,000 * x bytes = 800, 020 * x bytes. As you can see, way greater memory is
consumed by the second loop.

Running some tests, it is observed that on Chrome, the shallow size occupied by the
concatenated string during the execution of the first loop is 802, 160 bytes, or ~0.8 MB. The
shallow size occupied by the concatenated string during the execution of the second loop is
8, 002, 160 bytes, or ~8 MB.

[ 11 ]
Efficient Implementation of Basic Data Structures and Algorithms

The implications of this are dastardly, and the user can experience application crashes and
freezes due to memory overload, which would lead to poor user experience and if not
immediately corrected, very soon zero usability and lost business.

Now, let's take a look at string replacement.

String replacement
Take a look at the following code snippet:
function createString(): string {
return `Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry''s
standard dummy text ever since the 1500s, when an unknown
printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but
also the leap into electronic typesetting, remaining
essentially unchanged. It was popularised in the 1960s with the
release of Letraset sheets containing Lorem Ipsum passages, and
more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.`;
}
let baseString: string = createString();
const replacementCharacter: string = '|';
let time1: number = Date.now();
for (let i = 0; i < 50000; i++) {
baseString.split(' ').join(replacementCharacter);
}
let time2: number = Date.now();
console.log('Time difference (SplitJoin): ', time2 - time1);
time1 = Date.now();
for (let i = 0; i < 50000; i++) {
baseString.replace(/ /g , replacementCharacter);
}
time2 = Date.now();
console.log('Time difference (Replace_w_RegExp): ', time2 -
time1);

In the preceding code snippet, we start with the same base string as in previous examples.
Here, we have the objective of replacing every whitespace with the pipe character ('|').
For example, if the base string were "High Performance TypeScript", after applying our
replace logic, the resultant string would be "High|Performance|TypeScript".

[ 12 ]
Efficient Implementation of Basic Data Structures and Algorithms

Now, this string has a total of 127 whitespaces. We loop over the base string and perform
this replacement a total of 50,000 times. Let's understand the following two different
replacement options we are leveraging:

SplitJoin: Let's take a look at the following replacement option code snippet:

baseString.split(' ').join(replacementCharacter);

Let's split this into two pieces to better understand how this works, such
as split and join:

split: This method splits the string into an array of strings by separating
the string into substrings, as specified by an optional splitter character. Here,
we are using the whitespace (' ') as the splitter character. So, after we
apply baseString.split(' '), baseString is split into a string array of
length 128.
join: This method joins or combines all elements of a string array into a
string, as specified by an optional combiner character. Here, we specify the
pipe ('|') as the combiner character. Thus, the result
of baseString.split(' ').join('|') is a resultant string of the same
length as the base string (617 characters), with all the whitespaces replaced
by the pipe character.
Replace with RegEx: Let's take a look at the following replacement option code
snippet:

baseString.replace(/ /g, replacementCharacter);

The replace method returns a new string with some or all matches of a pattern
replaced by a replacement character. We again choose the pipe character as the
replacement character, and the pattern we choose is a regular expression '/ /g'.
We specify a RegEx by enclosing it within the forward slash character ('/').
Here, we specify a white space as the RegEx.

[ 13 ]
Efficient Implementation of Basic Data Structures and Algorithms

We include the g flag to indicate a global search and replace. If we are to


not include it, then only the first occurrence of a whitespace would be
replaced. There is also an "i" flag that can be used, which would mean
ignore case. In this case, it does not apply as we are not bothered about the
casing with the whitespace character.

If you were to analyze the two methods, you would note that in the SplitJoin method you
perform two passes around the input string -- first to break it down into smaller chunks,
and then to combine those chunks back into a whole string. This would involve as many
string concatenations as the number of chunks it got split into in the first place. The Replace
with RegEx options seems to take one pass around the input string, creating a new string
copy, character by character, looking for a pattern match along the way and replacing it
with the replacement character. An educated guess would be that the Replace with
RegEx option has a better performance.

Let's take a look at the results to find out! Note that these are a result of 127 replacements on
a 617 character long string, done 50,000 times:

Chrome (v56) IE (v11) Edge (v38)


SplitJoin 195 ms 405 ms 452 ms
Replace with RegEx 139 ms 144 ms 139 ms

As we predicted, the Replace with the RegEx method outperforms the SplitJoin method.
The difference between the two methods is more significant on IE and Edge. In terms of
real-world usage, string replacement is even more widely used than concatenation. Any
web/mobile application with a frontend framework that works with multiple backends, or
even a single backend, can run into the string replacement scenarios where data
interpretation across different systems varies and there's a need to replace some strings to
convert it into a format that the current system can understand. If done inefficiently, the
results could once again lead to a slower/sluggish UI rendering, higher network latencies,
incapability in using the application's full feature set due to the slower performance making
the application unusable and gives you a poor user experience overall.

As you can see, efficient implementation of basic data type manipulations have a far
reaching impact on the performance and usability of an application. Let's look at some other
data structures and constructs.

[ 14 ]
Efficient Implementation of Basic Data Structures and Algorithms

Classes and interfaces


For folks acquainted with object-oriented concepts, the use of classes and interfaces is well
known. It is the most basic way to encapsulate information. Classes encapsulate a common
data schema, and operations for all of its instances, and interfaces just encapsulate a schema
which needs to be implemented by any class that implements the interface.

These are the basics which you must already be familiar with. Instead of introducing some
simple examples of class and interface declaration, let's deep dive into an advanced usage
scenario, very close to how real-world modern web/mobile applications are structured. Pay
close attention to the following problem statement.

Let's assume we are a vendor company for another firm, lets say XYZ. Now, XYZ contacts
us and asks us to implement Social Network Feed Generator (SNFG). XYZ is building an
application to combine social network feed from all possible social networks, and displays
this aggregated feed to it's users. Let's assume a scenario in which a single universal key or
token that can authenticate a user against all of his/her social networks (let's not worry
about the security at this moment, as we are not trying to understand cryptography here!).
XYZ plans to pass us this key for it's users, and in return, wants an aggregated feed based
on several different criteria such as most recent updates, most popular updates, and so
on. Now, our job is simple --to provide an API to XYZ that it can use in it's application.

Let's get started building SNFG in an object-oriented way, making it extensible for future
updates. Take a look at the following code snippet:
// publicly accessible
export enum FeedStrategy { Recent, Popular, MediaOnly };

// internal
enum SocialMediaPlatform { Facebook, Instagaram, Snapchat,
Twitter, StackOverflow };

// publicly accessible
export interface IFeed {
platformId: SocialMediaPlatform;
content: string;
media: string
}

// publicly accessible
export interface IFeedGenerator {
getFeed(limit?: number): IFeed[];
}

// internal

[ 15 ]
Efficient Implementation of Basic Data Structures and Algorithms

class RecentFeedGenerator implements IFeedGenerator {


private authenticate(universalKey: string): void {
// autheticate user identity
}

public getFeed(limit?: number): IFeed[] {


/* if authenticated
{
custom algorithm to optimally calculate most recent social
media feed for the user, across all the available social
media platforms
} */
return []; /* return the results, returning empty array here to
satisfy method return type */
}
}

// internal
class PopularFeedGenerator implements IFeedGenerator {
private authenticate(universalKey: string): void {
// autheticate user identity
}

public getFeed(limit?: number): IFeed[] {


/* if authenticated
{
custom algorithm to optimally calculate most popular
social media feed for the user, across all the available
social media platforms
} */
return []; /* return the results, returning empty array here to
satisfy method return type */
}
}

/* you can have as many classes as you desire, or you can also
combine multiple feed fetching algorithms into single class */

// publicly accessible
export function FeedGeneratorFactory(feedStrategy: FeedStrategy,
universalKey: string): IFeedGenerator {
let feedGenerator: IFeedGenerator = null;
switch (feedStrategy) {
case FeedStrategy.Recent: {
feedGenerator = new RecentFeedGenerator();
break;
}
case FeedStrategy.Popular: {

[ 16 ]
Efficient Implementation of Basic Data Structures and Algorithms

feedGenerator = new RecentFeedGenerator();


break;
}
}
return feedGenerator;
}

We design a module called Feeder (we will be looking at modules and namespaces in
closer details in the next chapter). Within this module, we build the crux of our SNFG. The
idea is that XYZ can use the exported members (publicly accessible) of this module to
achieve its objective. Let's take a look at the exported members of Feeder in the following
code snippet:
export enum FeedStrategy { Recent, Popular, MediaOnly };

export interface IFeed { ... };

export interface IFeedGenerator { ... };

export function FeedGeneratorFactory(feedStrategy: FeedStrategy,


universalKey: string): IFeedGenerator { ... }

The most important exported function is FeedGeneratorFactory. XYZ can call this
function with it's desired FeedStrategy (which is also exposed as an enum), and
universalKey for the user it wishes to access the feed of. With this information,
what FeedGeneratorFactory does is completely abstracted. This function returns an
interface type IFeedGenerator. This is all that the developers of XYZ should really care
about. We expose an interface IFeedGenerator, any class implementing which
implements the function getFeed which takes in an optional limit parameter to specify
the upper limit on the number of desired feed items. From XYZ's perspective, they can
simply invoke the FeedGeneratorFactory function, and call the getFeed() function on
the returned IFeedGenerator implementation. Internally, based on the FeedStrategy
function, we return a different class. We could as well have put all of the logic into a single
class (although not a good idea). How we implement this is completely up to us and is
hidden from XYZ.

This is a classic example of abstraction and encapsulation, one of the key


concepts of object-oriented design.

[ 17 ]
Efficient Implementation of Basic Data Structures and Algorithms

The feed method returns an array of IFeed type, which is also an exposed interface.
Each IFeed consists of platformId to identify the social media platform the feed belongs
to, a string content, and string media, which is a URI pointing to the media used in the feed,
if any. The contents of IFeed can be discussed with XYZ and modified if needed.

All other members, such as the actual classes implementing the core logic of feed fetch, sort,
organize, most likely cache, and several other concepts which would need to be introduced
as the scale of this increases, are internal to us and totally abstracted from XYZ.

Now from XYZ's perspective, knowing this information, all they need to do is import our
module and use it in their application. One possible usage could be as illustrated in the
following code snippet:
import * as Feeder from "./vendor";

class FeedRenderer {
private recentFeedGenerator: Feeder.IFeedGenerator;
private popularFeedGenerator: Feeder.IFeedGenerator;

constructor(universalKey: string) {
this.recentFeedGenerator = Feeder.FeedGeneratorFactory
(Feeder.FeedStrategy.Recent, universalKey);
this.popularFeedGenerator = Feeder.FeedGeneratorFactory
(Feeder.FeedStrategy.Popular, universalKey);
}

public getRecentFeed(): Feeder.IFeed[] {


return this.recentFeedGenerator && this.recentFeedGenerator
.getFeed();
}

public getPopularFeed(): Feeder.IFeed[] {


return this.popularFeedGenerator &&
this.popularFeedGenerator.getFeed(10);
}
}

There are several ways to import and export modules, which we will explore in the next
chapter. In the preceding example, we are explicitly including a reference to the vendor.ts
file which we looked at earlier.

[ 18 ]
Efficient Implementation of Basic Data Structures and Algorithms

With this setup, XYZ gets access to the exposed members of our Feeder module. They
simply call the FeedGeneratorFactory function to get access to
two IFeedGenerator types, such as one that fetches the most recent feeds, and one that
fetches the most popular feeds. From their standpoint, they don't really care whether it's the
same implementation or two different implementations under the wraps. All they care is, it
is of the type IFeedGenerator. The FeedRenderer class would be called into by XYZ's UI
elements to render the fetched feed.

The preceding example is a classic illustration of a design pattern called


Factory Method Pattern. In our case, the
FeedGeneratorFactory function is the factory method that returns an
object without it's user (XYZ) explicitly having to specify the exact class of
the object that will be created.

The following diagram summarizes the factory pattern we've been discussing thus far:

[ 19 ]
Efficient Implementation of Basic Data Structures and Algorithms

Apart from the flexibility this offers to you as a vendor, in terms of internally managing the
concrete implementations, it also makes it easier for you to manage version updates and
rollbacks. Any new releases can be rolled out without breaking the consumer contract
(explicit consumer-driven contracts can be enforced too), and if anything were to break, you
can rollback to an earlier version, and the experience from the consumer's perspective
would be seamless.

This helps the consumer as well, in that if the preceding exposes API, becomes or is an
industry standard, and there are multiple such vendors available to choose from in the
market, the consumer can seamlessly switch between multiple vendors without having to
make major changes to their core code base.

As you can see, when leveraged wisely, classes and interfaces can have a high impact on the
longevity and scalability of your application, and consequently on it's performance.

Loops and conditions


Loops are one of the most common constructs in any language. It is a mechanism to execute
the same piece of logic multiple times. There are multiple ways to do so in TypeScript. Let's
take a look at some in the following code snippet:
const arr: Array<number> = [];
let temp: number = 0;

const randomizeArray = () => {


for (let i = 0; i < 50000; i++) {
arr[i] = Math.floor(Math.random() * 100000);
}
}

// dummy method
const dummy = () => null;

// for...in
const forinLoop = () => {
let dummy: number;
for (let i in arr) {
dummy = arr[i];
}
}

// for...of
const forofLoop = () => {
let dummy: number;

[ 20 ]
Efficient Implementation of Basic Data Structures and Algorithms

for (let i of arr) {


dummy = i;
}
}

// naive
const naiveLoop = () => {
let dummy: number;
for (let i = 0; i < arr.length; i++) {
dummy = arr[i];
}
}

const calculateTimeDifference = (func: () => void): number => {


randomizeArray();
const time1: number = Date.now();
func();
const time2: number = Date.now();
return time2 - time1;
}

console.log('Time Difference (forof): ', calculateTimeDifference


(forofLoop));
console.log('Time Difference (forin): ', calculateTimeDifference
(forinLoop));
console.log('Time Difference (naive): ', calculateTimeDifference
(naiveLoop));

In the preceding code snippet, we declare an array arr. We initialize it with 50,000 random
numbers. Then, we measure the time performance of three loops such as forof loop, forin
loop, and naive loop. Before we dig into the performance results, let's take a look at a side
note on the syntax.

We have declared the array using the generic array type, const arr:
Array<number> = [];. We can also declare it using the data-type-array
syntax, const arr: number [] = [];. Also, we've declared the
functions as constants, using the Lambda expressions. We could also write
them as old fashioned functions, function forinLoop() { ... }.
We are also passing functions as parameters, as
in, calculateTimeDifference(forofLoop). The function declaration
of this function is interesting, const calculateTimeDifference =
(func: () => void): number => { ... }. This basically says
that calculateTimeDifference is a function that takes a function which
takes zero arguments and returns void as an argument, and returns a
number.

[ 21 ]
Efficient Implementation of Basic Data Structures and Algorithms

Let's take a look at the following performance of these loops now:

Chrome (v56) IE (v11) Edge (v38)


forofLoop 1.4 ms 7 ms 4.4 ms
forinLoop 22.8 ms 16.2 ms 15.2 ms
naiveLoop 1.6 ms 11 ms 7.4 ms
As can be seen, the forof loop performs the best, followed by naive loop, followed by the
forin loop. These results are actually a little misleading. For one, the performance of the
naive loop can be greatly improved by storing the arr.length property in a variable and
using that in the loop statement, instead of accessing the array's property each time. In
addition to that, the preceding example is not really a strong case in point for the forin
loop. Let's take a look at another example which would highlight the advantages of using
the forin loop:
const calculateTimeDifference = (func: () => void): number => {
const time1: number = Date.now();
func();
const time2: number = Date.now();
return time2 - time1;
}

const generateGuid = (): string => {


return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
(c: string) => {
const r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

interface Map {
[key: string]: string;
}

const map: Map = {};

for (let i = 0; i < 50000; i++) {


map[(i+1).toString()] = generateGuid();
}

// for...in
const mapForIn = () => {
let dummy: string;
for (let key in map) {

[ 22 ]
Efficient Implementation of Basic Data Structures and Algorithms

dummy = key;
}
}

// for...of
const mapForOf = () => {
let dummy: string;
const keys = Object.keys(map);
for (let key of keys) {
dummy = key;
}
}

// naive
const mapForNaive = () => {
let dummy: string;
const keys = Object.keys(map);
for (let i = 0; i < 50000; i++) {
dummy = keys[i];
}
}

console.log('Time Difference (map:forof): ',


calculateTimeDifference(mapForOf));
console.log('Time Difference (map:forin): ',
calculateTimeDifference(mapForIn));
console.log('Time Difference (map:naive): ',
calculateTimeDifference(mapForNaive));

The preceding code snippet generates the following result:

Chrome (v56) IE (v11) Edge (v38)


forofLoop 8.6 ms 12.2 ms 10.8 ms
forinLoop 9.2 ms 8.2 ms 6.6 ms
naiveLoop 11.8 ms 10.4 ms 9.4 ms

On Chrome, the forof loop outperformed the forin loop, but only slightly. On IE and
Edge, the forin loop recorded the best performance, while the naive loop remained the
least efficient across all browsers. Thus clearly, the forin loop is the recommended for
looping over objects such as dictionaries. Based on the use case, one should choose the
option that most makes sense.

[ 23 ]
Efficient Implementation of Basic Data Structures and Algorithms

Conditional statements are one of the most commonly used constructs in any language. In
TypeScript, you may implement a conditional using the if..else statement or
the switch…case statement. Let's take a look at these constructs.

Consider the following if..else block:


let decision: number = Math.floor(Math.random() * 100) + 1; //
random // number between 1 and 100
if(decision === 1) {
// do something
} else if(decision === 2) {
// do something
} else if (decision === 3) {
// do something
} else if (decision === 4) {
// do something
} else if (decision === 5) {
// do something
} else if (decision === 6) {
// do something
} else if (decision === 7) {
// do something
} // ...
// ...
// ...
} else (decision === 100) {
// do something
}

The performance of the preceding code block would be the worst if decision is 100,
making 100 comparisons before our condition evaluates to true. If you notice,
this if..else chain is equivalent to a linear search, the time complexity of which in terms
of Big-Oh notation is O(n) where n is the total number of comparisons. In the worst case,
you would make n comparisons like in the preceding example. In the best case, the very
first comparison would evaluate to true. On average you would make n/2 comparisons. If
you have data points with the probability of different values that decision can take, you
can optimize the preceding if..else chain by making the higher probability comparisons
before the others. The time complexity of this optimized approach would still be O(n).

[ 24 ]
Efficient Implementation of Basic Data Structures and Algorithms

In order to improve the performance in a generic case, especially when the probabilities are
unknown, you can refactor the if..else chain to reflect binary search. In binary search,
you eliminate half of the choices at each stage, thereby yielding a logarithmic time
complexity O(lgn). Look at the following code snippet to get a better idea:
let decision: number = Math.floor(Math.random() * 100) + 1; //
random // number between 1 and 100
if (decision < 50) {
if (decision < 25) {
if (decision < 12) {
if (decision < 6) {
// all results < 6
if (decision < 3) {
// compare decision with 1 and 2
} else {
// compare decision with 3, 4 and 5
}
} else {
// all results >=6 and < 12
if (decision < 10) {
if (decision < 8) {
// compare decision with 6 and 7
} else {
// compare decision with 8 and 9
}
} else {
// compare decision with 10 and 11
}
}
} else { /* ... */ }
} else { /* ... */ }
} else { /* ... */ }

One thing that would strike you immediately with the preceding code snippet is that even
though it performs better than the linear checks, it's readability is a big pain. Code
maintenance is a big factor that would be impacted especially when working on large team
projects. It's a good time to look at the switch…case statement:
let decision: number = Math.floor(Math.random() * 100) + 1; //
random // number between 1 and 100
switch (decision) {
case 1: {
// do something
break;
}
case 2: {
// do something

[ 25 ]
Efficient Implementation of Basic Data Structures and Algorithms

break;
}
// ...
// ...
case 100: {
// do something
break;
}
default: {
// do something
}
}

On first look, the switch…case statement seems to be similar to the linear if..else
block. However, it is internally based on the browser you're running the script on, the
rendering engine would optimize the number of comparisons. Given this fact combined
with a much better code readability, you should choose the switch…case statement
whenever you can make single value comparisons.

For range comparisons, you would still need to use the if..else
statement, which can actually render optimal performance if implemented
efficiently.

Arrays and sorting


In TypeScript, you can declare arrays using the classic square bracket syntax, for
example, let arr: number[] = [74, 46, 32]; or, you can also declare arrays using
the Array<elementType> syntax, for example, let arr: Array<number> = [74, 46,
32];.

Let's take a look at a sorting example with arrays:


const arr: number[] = [];
let temp: number = 0;

const randomizeArray = () => {


for (let i = 0; i < 50000; i++) {
arr[i] = Math.floor(Math.random() * 100000);
}
}

// naive
const naiveSort = () => {

[ 26 ]
Efficient Implementation of Basic Data Structures and Algorithms

for (let i = 0; i < arr.length; i++) {


for (let j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}

// optimized
const optimizedSort = () => {
let swapped: boolean = true;
while (swapped) {
for (let j = 0; j < arr.length - 1; j++) {
swapped = false;
if (arr[j] > arr[j + 1]) {
swapped = true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}

const calculateTimeDifference = (func: () => void): number => {


randomizeArray();
const time1: number = Date.now();
func();
const time2: number = Date.now();
return time2 - time1;
}

In the preceding code snippet, we declare an array and initialize it with 50,000 elements,
each of which is a random number between 0 and 100,000. The sorting algorithm we're
looking at is bubble sort. Bubble sort works by bubbling the largest element to the end of the
array in each pass (assuming a non-decreasing sort).

[ 27 ]
Efficient Implementation of Basic Data Structures and Algorithms

The number of passes needed by this algorithm is one less than the number of elements.
Let's take a look at the following diagram to get a better idea:

[ 28 ]
Efficient Implementation of Basic Data Structures and Algorithms

As you can see in the preceding diagram, we start with a 6 element array. In Pass 1, we
make four comparisons starting from the first element, and performing a swap each time
we detect an order mismatch. For example, 87 > 12, which is a mismatch and hence we do a
swap. 87 > 45, so we swap again. 87 < 93, and so we do not swap. Finally 93 > 16 and 99 >
93, so we swap. At the end of Pass 1, we ensure that the largest element is at the end of the
array.

We perform four more such passes, ensuring that the largest element during that pass ends
up toward the end of the array.

Generalizing this for an n-element array, we can see that the total comparisons we will end
up making is (n-1)*(n-1), which when talking in terms of Big-Oh gives us a time
complexity of O(n2).

The preceding concept is implemented in the preceding code snippet under the
function naiveSort. While reading this, you may have already detected an inefficiency in
the preceding approach. We need not have (n-1) passes by rule of thumb. As you can see
at the end of Pass 4, we already have a sorted array and do not really need Pass 5. So, when
do we know when to stop? Answer: When there was no swap performed during a pass we
stop. This optimized approach is implemented in the preceding code snippet under the
function optimizedSort.

The preceding mentioned that optimization is one possible way to


optimize the naive bubble sort. Another option is to perform one
comparison less in each subsequent pass, the reason being that each pass
ensures that the largest element is at the end, so we keep making
redundant comparisons toward the end of the array at each pass. This
approach combined with the preceding approach will result in an even
more optimal sorting algorithm. The optimized approach has better
runtime, but in terms of Big-Oh complexity, they are still O(n2) algorithms.

The results, not surprisingly, are as follows:

Chrome (v56) IE (v11) Edge (v38)


naiveSort 7563 ms NaN NaN
optimizedSort 1 ms 58 ms 45 ms

[ 29 ]
Efficient Implementation of Basic Data Structures and Algorithms

As you can see, a simple optimization has massive impacts on performance. On Chrome, it
outperforms the naive implementation by gigantic amounts. The optimized sort runs as fast
as a millisecond! And the naive sort takes almost 8 seconds! On IE and Edge, the findings
are even more dire. As expected, the optimized sort runs fairly quickly. However, the naive
sort never completes and the web page crashes even before the sort can complete!

Once again, the time performance despite having contrasting comparison is not the most
critical factor. CPU utilization and to some extent memory consumption are the resources most
severely impacted. Just to give you some context, the average CPU utilization for a web
page running advanced chat applications is only 0.5-3%. However, when the preceding
script is executed on a web page, the CPU utilization shoots up to 30-35%! This is one of the
reasons why the web page crashes. Note that the preceding percentage values are on a two
core processor with a maximum speed of 2.81 GHz.

There are several web/mobile applications that may perform the sorting of such a massive
scale. Consider a travel booking application for instance. Among the several thousand
options, different levels of sorting are performed, sorting based on prices, timings, and so
on. An optimal algorithm powering these sorts is of vital importance. Any inefficiency will
manifest itself as either UI spinners spinning forever, or application/web page
crashes. Either of these scenarios would take a massive hit on your application's user
engagement and ultimately on your business.

Operators
Let's now take a look at the several available operators you can leverage in TypeScript.
Quite a few have already been implicitly introduced to you via code snippets from previous
sections. Let's formally declare all the operators:

Arithmetic operators: The most obvious class of operators are the arithmetic
operators, which are used to perform arithmetic operations. The most obvious
arithmetic operators are addition (+), subtraction (-), multiplication (*),
division(/), increment (++), decrement (--), and modulus (%). The modulus
operator returns the result of what remains after a number is divided by another
as a whole. For example, take a look at the following code snippet:

const x: number = 9/4; //evaluates to 2.25

const y: number = 9%4; // evaluates to 1

As the usage of the remaining operators is natural, let's look at the next class of
operators.

[ 30 ]
Efficient Implementation of Basic Data Structures and Algorithms

Relational operators: These operators are used to perform comparisons in


TypeScript. The common relational operators are equals (==), does not equal (!=),
greater than (>), less than (<), greater than or equals (>=), and less than or equals
(<=).

The equals (==) operator exists in TypeScript in two flavors, strict mode
and lenient mode. The == is the lenient mode, while the === or triple
equals is the strict mode. With strict mode, the evaluation of the
expression to true is less than lenient mode, because in lenient mode there
is implicit type conversion whereas in strict mode there is no such
conversion. For example, 16 == '16' evaluates to true, whereas 16 ===
'16' evaluates to false.

Logical operators: These operators are used to perform manipulations on


conditions. Most common logical operators are AND (&&), OR (||), and Negation
(!). These operators can be used in various contexts, for example:

const condition: boolean = x > 0 && x < 10; // simple


condition AND

this.instanceVariable && this.instanceVariable.DoOperation();


/* AND used to check for non-null instance variable, and then
perform the operation on that instance. */

// This could also be written as

if (this.instanceVariable) {
this.instanceVariable.DoOperation();
}

Bitwise operators: Apart from the preceding mentioned operators, there are
several bitwise operators, which perform advanced bit-level manipulations. Some
common bitwise operators are as follows:
Left shift (<<): Left shift shifts the bits in a number to the left, by the
specified number of bits, for example, (x << 2)
Right shift (>>): Right shift shifts the bits in a number to the right, by the
specified number of bits, for example, (x >> 2)
AND (&): The AND operator performs a bit-level AND on the bits of the
two specified operands, for example, (x & 4, which is x & 0...0100)

[ 31 ]
Efficient Implementation of Basic Data Structures and Algorithms

OR (|): The OR operator performs a bit-level OR on the bits of the two


specified operands, for example, (x | 4, which is x | 0...0100)
XOR (^): XOR performs a bit-level XOR on the bits of the two specified
operands, for example, ( x ^ y)
Negation (~): Negation flips the bits of a number, for example, (~x)

Some Important Bitwise Operator Hacks


1. x << 1 is the same as x * 2. 2. x >> 1 is the same as x / 2. 3. x & 0 will
always equal 0. 4. x | 1 will always equal 1. 5. x ^ x will always equal 0. 6.
~0 is 11...11 (as many bits as the system supports).

For the sake of completeness, lets also explore the typeof operator,
instanceof operator, and Compound Assignment Operators with the
help of the following code snippet:
// 1. compound assignments
let num: number = 40;
num *= 2; // num1 equals 80. this is same as num = num * 2

// 2. typeof
const str: String = 'test';
console.log(typeof num); // outputs number
console.log(typeof str === 'string'); // outputs true

// 3. instanceof
const arr: number[] = [1,2,3];
class ABC {};
const abc: ABC = new ABC();

console.log(arr instanceof Object); // outputs true


console.log(arr instanceof Array); // outputs true
console.log(abc instanceof Object); // outputs true
console.log(abc instanceof ABC); // outputs true
console.log(arr instanceof ABC); // outputs false

Compound assignment operator: The first operator in the preceding code


snippet is a compound multiplication assignment operator. This is the following
two-step process:
1. First is multiplication, temp = num * 2.
2. Second is assignment, num = temp.

[ 32 ]
Efficient Implementation of Basic Data Structures and Algorithms

Thus, writing num *= 2 is equivalent to writing num = num *2.


Similar to compound multiplication assignment, we can have compound
addition, subtraction, and division assignments. Take a look at the following
operators:

typeof: The second operator in the preceding code snippet is the typeof
assignment. As can be seen, typeof num prints number and typeof str
prints string.
instanceof: The third operator in the preceding code snippet is the
instanceof operator. As can be seen in the preceding code snippet, this can
be used to query a given object to find which class it is an instance of. This
can be useful in determining the implementing class of an object passed to a
method that accepts an interface type as a parameter.

Summary
In this chapter, we looked at some basic data structures, constructs, and algorithms, and
explored the performance impact of leveraging these in an efficient manner. We understood
how these performance tweaks play a major role toward the durability, scalability,
maintainability, and the performance of your application.

After exploring these basic constructs, let's take a look at some declaration basics that
TypeScript offers in our next chapter.

[ 33 ]
Variable Declarations,
2
Namespaces, and Modules
In this chapter, we will take a look at the declaration basics exposed by TypeScript.
Declarations are a way to specify the existence of an entity to the compiler. Besides this and
more importantly, the correct use of the declaration constructs is key in writing readable
and scalable code.

We will explore the following topics in this chapter:

Variable declarations: We will explore the three different variable declarations


TypeScript offers such as var, let, and const and compare and contrast the use
of each of them independently and in conjunction with each other.
Namespaces and modules: We will take a look at the logical grouping of code
into readable and modular regions, with the help of namespaces and modules. We
will understand how to use these efficiently to write loosely coupled, modular,
and scalable components.

Variable declarations
There are several different ways in which variables can be declared in TypeScript, such
as var, let, and const. There's a distinct difference between these, but the implications
that arise as a result of it are quite subtle. Instead of introducing the theory first, let's take a
look at some example declarations in the following code snippets and then deduce the
theory from it.
Exploring the Variety of Random
Documents with Different Content
+ − The Times [London] Lit Sup p426 Jl 1
’20 140w
Wis Lib Bul 16:237 D ’20 50w

ASHMUN, MARGARET ELIZA. Marian Frear’s


summer. *$1.75 (3c) Macmillan

20–10729

Marian Frear and her mother live together on an isolated little


farm on the lake shore. They have been very happy together and keep
busily occupied with the vegetable garden that supplies their living.
But Marian misses the companionship of other girls and the lack of
educational opportunities troubles both mother and daughter. Then
a happy family of young people comes to spend a summer on the
lake. Marian learns to play with other young people and in the fall
finds the desired way to education open to her.

Booklist 17:120 D ’20

“A cheerful, wholesome, natural story for girls.”

+ Outlook 125:615 Ag 4 ’20 20w

“The young people are simple and natural and the incidents are
never strained to produce dramatic effects, but those who have lived
in the country may feel that the absolute superiority of Marian and
her mother to all their neighbors is exaggerated.”

+ − Wis Lib Bul 16:197 N ’20 100w

ASLAN, KEVORK. Armenia and the Armenians


from the earliest times until the great war (1914).
*$1.25 Macmillan 956.6
20–1701

“In this little volume an Armenian historian gives a concise


account of the rise and progress of his people, including the
formation of Armenian royalty, the early religious ideas and customs,
the conversion to Christianity, the dawn of Armenian literature, and
finally the four centuries of bondage to the Turk. Many little-known
facts have been gleaned from the somewhat obscure records of this
long ill-treated people.” (R of Rs) “The work is translated from the
original French by Pierre Crabites, whose introduction is an
impassioned plea for Armenian independence.” (Dial)

“While at times the author seeks to present his nation in the most
favorable light, as in the omission of any mention of the outrages
perpetrated by the revolutionary societies at the close of the
nineteenth century, his book is free from any attempt at propaganda.
Unfortunately, this cannot be said of the preface written by M.
Crabites.” D: Magie

+ − Am Hist R 25:748 Jl ’20 500w

“It is a concise and readable outline, giving not only the main
currents of political development but also some information
concerning economic and social organization.”

+ Am Pol Sci R 14:363 My ’20 60w

“Unlike most writings on the subject the history is stated in a


matter of fact way free from propaganda.”
+ Booklist 17:23 O ’20
Dial 68:668 My ’20 40w

“There is grievous need of a map and almost equally of an index.


But the book is good and solid, sober with historical sense and
conscience.”

+ Review 2:604 Je 5 ’20 450w


R of Rs 61:446 Ap ’20 120w

“A carefully prepared, though naturally sympathetic, history.”

+ Springf’d Republican p10 My 20 ’20


200w
The Times [London] Lit Sup p242 Ap
15 ’20 80w

ASQUITH, MRS MARGOT (TENNANT).


Margot Asquith, an autobiography. 2v il *$7.50
Doran

20–20995

With astonishing frankness Mrs Asquith tells the story of her life
and when she says in her preface that she has taken the
responsibility of the telling entirely upon herself, one can easily
believe her. Her dash and courage and unconventionality, her
affectionate nature and clever wit, her social position and close
association with events and people of prominence make the book
unusual. In her own words, she has related of her “manners, morals,
talents, defects, temptations and appearance” as faithfully as she
could. Her reminiscences are all of a personal nature without
reference to politics and public affairs. Both books are indexed and
illustrated.

“Mrs Asquith is a sentimentalist, and a sentimentalist of the worst


kind, one who keeps it all for herself. She imagines that she is a very
rare, very misunderstood person. She has made a serious mistake in
writing this book; in it she delivers up her secret to the first-comer.
Her book is really a very dull one unless it is regarded as an
unconscious self-revelation. From that aspect it is quite interesting
though the type it reveals is not very intriguing.” J. M. M.

− Ath p610 N 5 ’20 1850w


Booklist 17:152 Ja ’21

“The self-revelations of Margot Asquith and those of Benvenuto


Cellini present more than one parallel. Margot Asquith’s
autobiography is essentially human. She has painted a portrait of
herself that will live, and she has filled in the background with
pictures of many who are sure of a permanent place in the history of
English literature and of the politics of England.” J. C. Grey

+ Bookm 52:356 D ’20 1250w

“Few writers have at once the intimate acquaintance and the


analytic tendency to put forward such keen and living figures. We
can hope to possess very few such living documents as is this record
of the last forty years.” D. L. Mann

+ Boston Transcript p4 N 27 ’20 1400w

Reviewed by H: W. Nevinson

+ − Nation 111:sup657 D 8 ’20 1900w

“Being a woman born into a society where her game was to be


charming, and where she had no chance to be seriously educated, we
find her at the age of fifty-six publishing idiocies that Marie
Bashkirtseff was too sophisticated to utter at fourteen, and never
once attaining Marie Bashkirtseff’s noble realization that ‘if this book
is not the exact, the absolute, the strict truth, it has no raison d’être.’”
F. H.

− + New Repub 25:77 D 15 ’20 2600w

“Her lack of reticence is, plainly, offensive to good taste. It is not


the less offensive because it is apparently entirely unconscious. The
surprising thing is, however, that with all the material for interesting
memoirs that Mrs Asquith should have stored away in her mind, she
has given us relatively so little that is of any permanent value.”
Stanley Went

− + N Y Evening Post p8 D 4 ’20 1700w

“The book is fascinating from the first page to the last.”

+ N Y Times p3 N 14 ’20 1650w


Reviewed by R. R. Bowker

+ Pub W 98:1883 D 18 ’20 150w

Reviewed by E. L. Pearson

Review 3:531 D 1 ’20 500w

“It is after a fashion moral in tone, even religious, as is apparently,


the writer’s character; it is reticent in political matters; and it is
undeniably clever. With a little more pruning Mrs Asquith’s
‘Autobiography’ might have been a valuable and innocent record of a
memorable society and an interesting period; as it stands, it is a
scandal. Not, as we have said, for moral reasons in the narrower
sense of the word, but for its wanton disregard of reticence and
decorum.”

+ − Review 3:623 D 22 ’20 1000w

“The fascination of the book lies in its bold defiance of British


literary and social tradition, and its studied departure from the
conventional.”

+ R of Rs 63:109 Ja ’21 90w

“A book, particularly one written on some of the first figures in the


country, should have some solid worth, and represent some
substantial judgment. Mrs Asquith prides herself on saying exactly
what she likes, on writing exactly what she thinks; but the result is
not often judicious, nor of any importance, except as a tribute to the
taste of the age.”
− Sat R 130:418 N 20 ’20 880w

“In spite of the errors in taste, and of certain occasional breaks in a


style quite admirable when its purpose is considered, the book
justifies those who have declared it to be ‘a true piece of literature’
with all that such words import.”

+ − Spec 125:598 N 6 ’20 3000w

“This autobiography is a revealing as well as an amazing book. The


toes on which it treads are all English. Americans may not approve
entirely of its material and its bumptious method, but they still find
in it much significance and a great deal of entertainment.”

+ − Springf’d Republican p8a D 5 ’20 1350w

“Mrs Asquith has moved through great scenes; but the motion is a
flitting, rather than an act of spiritual observation, and therefore
when she sits down to recall her impression, it is apt to lack both
sharpness and refinement.”

− Springf’d Republican p8 D 18 ’20 650w


(Reprinted from London Nation)

“She is not well equipped for the panoramic display of the outer
world, and the remarkable fulness of her opportunity in that
direction is largely wasted. Mrs Asquith is no story-teller, it is not her
line; she lacks the seeing eye and the vivifying phrase. And yet she
elects to write a book that is all storytelling, all an attempt to
reproduce the brilliant phantasmagoria in which she has lived.”
+ − The Times [London] Lit Sup p716 N 4
’20 2200w

ASTON, SIR GEORGE GREY. Memories of a


marine, an amphibiography. il *$5 Dutton

(Eng ed 20–8797)

“This volume is in autobiographic form and while it does not


pretend to be a complete story of the author’s life it is written along
autobiographic lines. The writer gives us some account of his
subaltern days, when he was a student and then a budding naval
officer. Then he recalls the period of the disturbances in Ireland and
the Phœnix park murders. But he soon leaves this region for the East.
It is the pleasant side of naval service that he shows us. After this sea
experience, the writer tells of his transfer to the admiralty office in
London and his experiences. He gives an agreeable account of Queen
Victoria’s golden jubilee in 1887, at which the German Crown Prince
Frederick, father of the recent Kaiser, was a conspicuous figure.
Then, in 1889, Sir George though not then knighted—had an
experience at the staff college. Then, later, there were some vigorous
experiences to record in connection with the war in South Africa.”—
Boston Transcript

“The book is one to be read with enjoyment and interest.”

+ Ath p1243 N 21 ’19 120w

“Sir George throughout his narrative is chatty, never tedious or


prolix and intersperses his story with frequent anecdotes, which are
always fresh and well told.”

+ Boston Transcript p4 S 4 ’20 450w


+ Brooklyn 12:132 My ’20 40w
+ Sat R 128:563 D 13 ’19 1200w

“Altogether, he has given us an exceedingly attractive addition to


the literature of reminiscence.”

+ Spec 124:460 Ap 3 ’20 1650w


+ The Times [London] Lit Sup p638 N 13
’19 750w

ATHEARN, WALTER SCOTT. National system


of education. (Merrick lectures) *$1.50 Doran 377

20–4029

“Professor Athearn frankly states that the church cannot ask the
state to teach religion, but the church can teach religion at odd hours
during the week and on Sunday. The church can and must organize
and administrate a national system of religious education that will
parallel and correlate with the national secular system which is in
process of formation at the present time. He regards the Smith-
Towner bill as a large step in the direction of a unified, national,
secular system of education, and accepts it as a challenge to the
educational leadership of the church to produce a program which
will be equally scientific, equally democratic, and equally prophetic.
His discussion of national control, or direction, of a system of secular
and religious education is extremely worth while at this, the most
critical, time in the history of education in the United States.”
(School R) “Bibliography on educational organization and
administration.” (Booklist)

Reviewed by J. A. Artman

+ Am J Soc 26:240 S ’20 220w


+ Booklist 16:260 My ’20
+ El School J 20:633 Ap ’20 180w
St Louis 18:217 S ’20 70w

“Timely and vital book.”

+ School R 28:392 My ’20 400w

ATTLEE, CLEMENT RICHARD. Social worker.


*$2.50 Macmillan 360

20–19448

“‘The social service library,’ of which this is the first volume, is


issued under the ægis of the University of London Ratan Tata
department of social science and administration. The subjects dealt
with in order, each subject being treated under certain general sub-
headings, are Social service and citizenship, Charities (these are
classified, and one section discusses Waste and over-lapping),
Organization, Social service in conjunction with central and
governing authorities, the Qualifications and training of the social
worker (a talk on the subject which would be of great value to all
entering on social work), Religious agencies, The settlement
movement (one of the subheads is, The school mission), Varieties of
social worker; and there is an instructive chapter at the end on The
social service of the working classes (The friendly society—The trade
union—The cooperative society—The working men’s club—self-
education).”—The Times [London] Lit Sup

Ath p428 Mr 26 ’20 90w


Cleveland p92 O ’20 20w

“It is written in a philosophical spirit and with close-hand


knowledge of the subject. Although its descriptions of the various
agencies is based on British material, the book as a whole is bound to
be useful for the American social worker and student of social
problems.” J. H. T.

+ Int J Ethics 31:117 O ’20 90w

“The book is full, racily written, and made alive with interesting
first-hand illustration.”

+ Nature 106:498 D 16 ’20 350w

“To an American social worker possibly the chief interest of the


book is the philosophy of the author. He reflects a modern faith in
the power of the community as such to deal with the conditions that
menace social welfare.” P. R. Lee
+ Survey 44:731 S 15 ’20 1200w

“The book is a singularly thoughtful and instructive study of a


subject in which a widely interested public really needs well-
considered guidance.”

+ The Times [London] Lit Sup p175 Mr 11


’20 320w

AUDOUX, MARGUERITE. Marie Claire’s


workshop; tr. by F. S. Flint. *$2 (3½c) Seltzer

21–759

“Marie-Claire,” to which “Marie Claire’s workshop” is a sequel, was


published in 1911. Marie Claire is now employed as a seamstress in a
workshop in Paris, and the book describes her life and work there,
with character studies of her shopmates. Monsieur and Madame
Dalignac are the kindly proprietors and they are portrayed vividly as
are Sandrine and Bouledogue and Duretour and her lover and
Gabielle and the others. There is also Clement, Madame Dalignac’s
nephew, who wishes to make Marie Claire his wife. The strain of
working against time to fill a promised order, the monotony of the
dull season when there is no work, the everyday contact of the girls,
all enter into the picture.

“Very simple and very real, told with sympathy, grace and a fine,
sure artistry, this picture of ‘Marie Claire’s workshop’ is a most
appealing book.”
+ N Y Times p20 N 21 ’20 640w

“In short, this is a special type of realism, and the cumulative effect
of it ... recalls as its nearest parallel, not prose but verse, Hood’s
‘Song of the shirt.’” Calvin Winter

+ Pub W 98:1195 O 16 ’20 280w

“This is a book for gentle souls; although it is too deeply human for
the ingenuous.” A. G. H. Spiers

+ Review 4:59 Ja 19 ’21 1100w

“Possesses all the qualities of its forerunner, truth, serenity,


freshness, keen observation, united with a deeper understanding of
human nature and an even wider sympathy.”

+ Spec 125:708 N 27 ’20 540w


The Times [London] Lit Sup p685 O 21
’20 30w

AULT, NORMAN. Dreamland shores. il *$3


Dodd 821

Poems for children with such titles as My dog, Clouds, Ducks,


Pirate gold, The wind, The weathercock, The magic garden, Seasons,
Noah’s ark, The moon’s adventure, The clock-man, Travels, A castle
in the air, Tree-top. There are six colored plates and other
illustrations by the author.

AUMONIER, STACY. One after another. *$2


Macmillan

20–15345

“Success jostles failure in the pages of Mr Aumonier’s latest novel.


His hero is his own biographer, and we follow him through a
picturesque childhood, along a divergent manhood, and into a more
or less ebullient middleage. When the end of the story, but not the
end of his life, is reached, we find that after adverse beginnings he
has become a prosperous business man, whose temperamental sister
has caused him more trouble than any of his own emotions, that he
has been twice a happily wedded husband, that he is the loving father
of a very desirable daughter, and the expectant grandfather of a child
whose father has sacrificed himself to the god of battle in the great
war. Except for that single episode near the end of the story, the
chronicle has to do with the ways of national, if not individual
peace.”—Boston Transcript

“It is rich and poor, cold and hot, dull and deeply interesting. But
the impression of the whole is of something which has just not
succeeded.” K. M.

+ − Ath p702 My 28 ’20 470w

“Readers who care for presentation of character rather than for


plot, will like this, though some describe it as tedious. Not for the
small library.”
+ − Booklist 17:156 Ja ’21
“Although his theme and the form of his story are
conventional, Mr Aumonier has written in ‘One after
another’ an unusual novel.” E. F. E.

+ Boston Transcript p6 S 8 ’20 1400w

“‘One after another,’ though reminiscent of Butler and Bennett, is


of the very recent type, the vegetable school, that deals pleasantly
with mediocrity at its best.”

+ − Dial 59:663 D ’20 70w

“By this sharp definition of the generations blended with his


brooding sense of life’s fundamental continuance, Mr Aumonier has
made his book as suggestive as it is entertaining and as philosophical
as it is concrete.” L. L.

+ Nation 111:sup428 O 13 ’20 320w

“The novel is one whose appeal will be to those who care for style
and thought rather than for plot and incident. It is a better book than
‘The Querrils.’”

+ N Y Times p23 S 19 ’20 650w

“Naturally the interest is of the quiet rather than of the exciting


order, but the situations are well thought out and the human interest
and humor of sound quality.”
+ Outlook 126:333 O 20 ’20 90w

“Here is something to be read by both the new generation and the


old, for it links them together, with a fine understanding of both.” D.
W. Webster

+ Pub W 98:661 S 18 ’20 240w

“The development of the narrator’s character is, to our mind,


particularly well done—a very difficult task, and taken altogether the
author more than justifies the high opinion we hold of his abilities.”

+ Sat R 130:40 Jl 10 ’20 90w

“The book tends more to reflection than to entertainment, and is


considerably above the usual run of modern novels.”

+ Spec 125:408 S 25 ’20 280w

“Mr Aumonier in this work, while displaying a good deal of


keenness alike of observation and thought, fails in the essential task
of creating people that impress us as individual and significant. Mr
Aumonier’s touch, however, is incisive and dramatic. And, in
intention at least, he is not commonplace.”

+ − Springf’d Republican p11a S 12 ’20


240w

“The scenes are described with the ability which ‘The Querrils’
showed Mr Aumonier to possess; but the book is less carefully
constructed, and the sense of incomplete finality which marred the
effect of the earlier novel in this one is more obtrusive. Mr Aumonier
studies situations rather than characters, and in contriving a
situation with a climax that is dramatic but not ‘stagey’ he has a
particular skill. At the same time, the book has a tendency to fall into
vaguely connected episodes, while the characters approximate too
closely to collections of impersonal attributes.”

+ − The Times [London] Lit Sup p351 Je 3


’20 430w

AUSTIN, MARY (HUNTER) (MRS


STAFFORD W. AUSTIN). No. 26 Jayne street.
*$2 (2½c) Houghton

20–9713

The action of the story takes place in the year after America’s
entrance into the war. Neith Schuyler, the heroine, has lived abroad
with an invalid father for a number of years, and following his death
has done relief work in France. She returns home hoping to learn to
understand America. To come nearer to the problem she leaves the
luxurious home of her two great aunts and takes a modest apartment
on Jayne street, just off Washington square. Here she comes into
contact with many shades of radical opinion and contrasts it with the
“capitalistic” attitude of her own family and friends. Two men fall in
love with Neith, Eustace Bittenhouse, an aviator, and Adam Frear, a
labor leader. She becomes engaged to Adam and then learns that
there has been another woman in his life, Rose Matlock, one of the
radical group. The attitude of the two women, who represent the new
feminism, puzzles Adam and he leaves for Russia. Eustace is killed in
France and Neith is left to grope her way into the future alone.
“Rather obscure and vague in some places, it will not have many
readers.”

+ − Booklist 16:345 Jl ’20

“Both in subject and in treatment, Mrs Austin’s work discloses its


kinship to the social novel of Wells.”

+ Dial 69:432 O ’20 60w

“Mrs Austin’s is a sincere and intelligent handling of an intricate


subject. Owing to her careful consideration and presentation of the
attitudes of her characters the book moves slowly, but it is easy to
feel the dynamic forces behind it.” H. S. G.

+ Freeman 1:597 S 1 ’20 680w

“Her attempt is original and subtle and its subtlety of presentation


is heightened by the fact that, before writing this story, Mrs Austin
seems to have steeped herself in Henry James.” Ludwig Lewisohn

+ Nation 110:827 Je 19 ’20 550w

“One should not chide Mrs Austin too much for her somewhat
blurred vision of the surface, since the greatness of her work lies in
the much rarer faculty, which she possesses, of being able to focus on
the inner significances.” J. C. L.

+ − New Repub 24:151 O 6 ’20 900w


“It gives you no more idea of conditions among New York radicals
than do the New York newspapers. The story moves slowly and
uninterestingly.” Henrietta Malkiel

− N Y Call p11 Jl 25 ’20 1000w

“The novel which is written primarily for some purpose outside


itself is a novel which from the beginning is heavily handicapped.
Usually the characters tend, in such instances, to become mere
mouthpieces to express such divergent views as the author may wish
to have uttered, and its situations are likely to descend into the
condition of mere obvious illustrations. Mrs Austin’s new novel, ‘No.
26 Jayne street,’ has escaped none of these dangers. The book is very
long, more than a little intricate, and at times profound.”

− + N Y Times 25:271 My 23 ’20 850w


+ Outlook 125:431 Je 30 ’20 50w

“Earnestness and background and an adroit hand belong to it, but


all its data, its types, its ‘ideas’ are recognizable and timely. Its style
may easily be called admirable. But its art conceals nothing. You do
not lay down the book with the feeling that it is a big interpretation
effortlessly embodied in its predestined form.” H. W. Boynton

− + Review 3:73 Jl 21 ’20 1050w

AUTOBIOGRAPHY of a Winnebago Indian, ed.


by Paul Radin. (Publications in American
archaeology and ethnology) pa $1 Univ. of Cal. 970.2
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebooknice.com

You might also like