• Stars
    star
    123
  • Rank 277,893 (Top 6 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created over 11 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Extremely fast string formatting

Fastring

Join the chat at https://gitter.im/Atry/fastring Scala CI Latest version Scaladoc

Fastring is a string formatting library for Scala. Fastring is also designed to be a template engine, and it is an excellent replacement of JSP, Scalate or FreeMarker.

It's simple to use

Fastring uses string interpolation syntax. For example, if you are writing a CGI page:

import com.dongxiguo.fastring.Fastring.Implicits._
def printHtml(link: java.net.URL) {
  val fastHtml = fast"<html><body><a href='$link'>Click Me!</a></body></html>"
  print(fastHtml)
}

It's extremely fast

I made a benchmark. I used 4 different ways to create a 545-characters string.

  1. Fastring (fast"Concat with $something" syntax);
  2. String concatenation (s"Concat with $something" syntax);
  3. Handwritten StringBuilder (stringBuilder ++= "Build from " ++= something syntax);
  4. java.util.Formatter (f"Format with $something" syntax).

This is the result from my Intel i5-3450 computer:

Fastring
import com.dongxiguo.fastring.Fastring.Implicits._
def fast(a: Int) =
  fast"head ${
    (for (j <- 0 until 10 view) yield {
      fast"baz$j $a foo ${
        (for (i <- 0 until 4 view) yield {
          fast"$a i=$i"
        }).mkFastring(",")
      } bar\n"
    }).mkFastring("<hr/>")
  } tail"

fast(0).toString

Took 669 nanoseconds to generate a 545-characters string.
(Simple and fast)
String concatenation
def s(a: Int) =
  s"head ${
    (for (j <- 0 until 10 view) yield {
      s"baz$j $a foo ${
        (for (i <- 0 until 4 view) yield {
          s"$a i=$i"
        }).mkString(",")
      } bar\n"
    }).mkString("<hr/>")
  } tail"

s(0)

Took 1738 nanoseconds to generate a 545-characters string.
(Simple but slow)
Handwritten StringBuilder
def sb(sb: StringBuilder, a: Int) {
  sb ++= "head "
  var first = true
  for (j <- 0 until 10 view) {
    if (first) {
      first = false
    } else {
      sb ++= ""<hr/>""
    }
    sb ++=
      "baz" ++= j.toString ++=
      " " ++= a.toString ++= " foo ";
    {
      var first = true
      for (i <- 0 until 4 view) {
        if (first) {
          first = false
        } else {
          sb ++= ","
        }
        sb ++= a.toString
        sb ++= " i="
        sb ++= i.toString
      }
    }
    sb ++= " bar\n"
  }
  sb ++= " tail"
  sb
}

val s = new StringBuilder sb(s, 0) s.toString

Took 537 nanoseconds to generate a 545-characters string.
(Fast but too trivial)
java.util.Formatter
def f(a: Int) =
    f"head ${
      (for (j <- 0 until 10 view) yield {
        f"baz$j $a foo ${
          (for (i <- 0 until 4 view) yield {
            f"$a i=$i"
          }).mkString(",")
        } bar\n"
      }).mkString("<hr/>")
    } tail"

f(0)

Took 7436 nanoseconds to generate a 545-characters string.
(Simple but extremely slow)

Fastring is so fast because it is lazily evaluated. It avoids coping content for nested String Interpolation. Thus, Fastring is very suitable to generate complex text content(e.g. HTML, JSON).

For example, in the previous benchmark for Fastring, the most of time was spent on invoking toString. You can avoid these overhead if you do not need a whole string. For example:

// Faster than: print(fast"My lazy string from $something")
fast"My lazy string from $something".foreach(print)

You can invoke foreach because Fastring is just a Traversable[String].

Utilities

There is a mkFastring method for Seq:

// Enable mkFastring method
import com.dongxiguo.fastring.Fastring.Implicits._

// Got Fastring("Seq.mkFastring: Hello, world")
fast"Seq.mkFastring: ${Seq("Hello", "world").mkFastring(", ")}"

// Also works, but slower:
// Got Fastring("Seq.mkString: Hello, world")
fast"Seq.mkString: ${Seq("Hello", "world").mkString(", ")}"

And a leftPad method for Byte, Short, Int and Long:

// Enable leftPad method
import com.dongxiguo.fastring.Fastring.Implicits._

// Got Fastring("Int.leftPad:   123")
fast"Int.leftPad: ${123.leftPad(5)}"

// Got Fastring("Int.leftPad: 00123")
fast"Int.leftPad: ${123.leftPad(5, '0')}"

Installation

Put these lines in your build.sbt if you use Sbt:

libraryDependencies += "com.dongxiguo" %% "fastring" % "latest.release"

See http://mvnrepository.com/artifact/com.dongxiguo/fastring_2.12 if you use Maven or other build systems.

Note that Fastring requires Scala 2.10, 2.11 or 2.12.

More Repositories

1

scalajs-all-in-one-template

The All-in-One Scala.js static web project template
Scala
59
star
2

protoc-gen-as3

Automatically exported from code.google.com/p/protoc-gen-as3
ActionScript
53
star
3

memcontinuationed

Memcached client for Scala
Scala
50
star
4

protoc-gen-haxe

Protocol Buffers compiler and run-time library for Haxe
Haxe
35
star
5

hoo

Haxe Operator Overloading
Haxe
15
star
6

Control.Dsl

An alternative to monads in do notation
Haskell
11
star
7

commons-continuations

Utilities for Scala continuations
Scala
10
star
8

go-for-ever

首尾相接的围棋
9
star
9

tail-call-proxy

Delayed initialized objects that support tail-call optimization
TypeScript
9
star
10

Curried.scala

The implementation of the Scala proposal: SIP-45 - Curried Varargs
Scala
9
star
11

zero-log

Automatically exported from code.google.com/p/zero-log
Scala
7
star
12

Dsl.scala-akka-actor

Scala
5
star
13

pttrt

Pass Them To Run-Time
Scala
5
star
14

sbt-cppp

Cross-Project Protobuf Plugin for Sbt
Scala
5
star
15

ReactToBindingHtml.scala

React / Binding.scala / html.scala Interoperability
Scala
4
star
16

immutable-future

A set of DSL for asynchronous programming, in the pure functional favor.
Scala
3
star
17

almond-images

Docker images for almond
3
star
18

nix-ld-so-cache-test

Nix
2
star
19

FutureBinding.scala

Scala
2
star
20

scala-junction

Create NTFS junction point from Scala or Java.
Scala
2
star
21

nameBasedXml.scala-0

Scala
2
star
22

as3recording

Automatically exported from code.google.com/p/as3recording
ActionScript
1
star
23

deeplearning-scala

CSS
1
star
24

swc2dot

Automatically exported from code.google.com/p/swc2dot
Scala
1
star
25

XmlExtractor.scala

Scala
1
star
26

JsPromiseBinding.scala

Scala
1
star
27

continuation.scala

Scala
1
star
28

MaximumUniqueSubarray

Scala
1
star
29

Binding.scala-sample

Scala
1
star
30

scaladoc-macro-annotations

Scala
1
star
31

aws-ec2-instance-pool

AWS EC2 instance pool
Haxe
1
star
32

deeplearning.thoughtworks.school

CSS
1
star
33

Route.scala

Scala
1
star
34

trigger-inline-macro-from-compiler-plugin

Scala
1
star
35

islandmap

Scala
1
star