Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining a locale using expressions? #882

Closed
alturkovic opened this issue Jul 13, 2023 · 9 comments
Closed

Defining a locale using expressions? #882

alturkovic opened this issue Jul 13, 2023 · 9 comments

Comments

@alturkovic
Copy link

I would like to evaluate an expression using a dynamically specified locale. A user needs to be able to specify both the expression and locale.

Is it possible to pass a specific locale to Faker.expression? Currently, if the user specifies expression such as #{Name.firstName}, they cannot specify the locale for which the name should be generated.

Do I need to construct a new Faker instance per call with the defined locale?

@snuyanzin
Copy link
Collaborator

depending on your customer you might be interested in datafaker-gen(datafaker based configurable generator ) https://github.com/datafaker-net/datafaker-gen where it's possible to specify locale

@snuyanzin
Copy link
Collaborator

snuyanzin commented Jul 13, 2023

Do I need to construct a new Faker instance per call with the defined locale?

no, you can do it like that

Faker faker = new Faker();
faker.doWith(() -> faker.expression("#{Name.firstName}"), Locale.GERMAN);

@alturkovic
Copy link
Author

Amazing work with this library! Thank you for the doWith tip and the link, I'll check it out

@alturkovic
Copy link
Author

@snuyanzin the only thing I noticed is that this operation is not thread-safe. Is there a multi-threaded environment alternative?

@kingthorin
Copy link
Collaborator

Please be more specific.

@snuyanzin
Copy link
Collaborator

no, it's not thread safe
however in datafaker initialization of Faker is very cheap in compare with javafaker it is about 100 times faster (we made some measurements for previous versions https://www.datafaker.net/documentation/performance170/#initialization)

so it's possible to create a faker per thread or even per task and it will be cheap (based on same measurements) performance of creation a new instance of faker is comparable with performance of simple expression evaluation. In case of complex expression initialization will be faster

@alturkovic
Copy link
Author

alturkovic commented Jul 13, 2023

Please be more specific.

Each doWith call seems to mutate the current context, so it is not safe to use with multiple threads. I made this example:

fun main() {
    val faker = Faker()

    val threads = mutableListOf<Thread>()
    repeat(1000) {
        val locale = if (faker.bool().bool()) Locale.ENGLISH else Locale.JAPAN

        threads.add(Thread {
            val result = faker.doWith({faker.expression("#{Name.firstName}")}, locale)
            println("[$locale] $result")
        })
    }

    threads.forEach { it.start() }
}

There are many entries for Japanese locale containing english names and vice-versa.

no, it's not thread safe however in datafaker initialization of Faker is very cheap in compare with javafaker it is about 100 times faster (we made some measurements for previous versions https://www.datafaker.net/documentation/performance170/#initialization)

so it's possible to create a faker per thread or even per task and it will be cheap (based on same measurements) performance of creation a new instance of faker is comparable with performance of simple expression evaluation. In case of complex expression initialization will be faster

Will each Faker lookup using the resolver load the values from files into memory? In other words, should I be worried about memory consumption with instancing a new Faker per call?

@snuyanzin
Copy link
Collaborator

snuyanzin commented Jul 13, 2023

Will each Faker lookup using the resolver load the values from files into memory?

only if you request it.
It is lazy(after #33 and some other improvements), meaning that it loads files only for the provider which was invoked. If some providers are not invoked, then files for them will not be loaded. This one of the diff between datafaker and javafaker

@alturkovic
Copy link
Author

Awesome, thanks for all the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants